xref: /freebsd/contrib/llvm-project/libcxx/include/future (revision 9ec406dc40df40f5e40672437517d1f3fe78149b)
10b57cec5SDimitry Andric// -*- C++ -*-
20b57cec5SDimitry Andric//===--------------------------- future -----------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_FUTURE
110b57cec5SDimitry Andric#define _LIBCPP_FUTURE
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    future synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
190b57cec5SDimitry Andricenum class future_errc
200b57cec5SDimitry Andric{
210b57cec5SDimitry Andric    future_already_retrieved = 1,
220b57cec5SDimitry Andric    promise_already_satisfied,
230b57cec5SDimitry Andric    no_state,
240b57cec5SDimitry Andric    broken_promise
250b57cec5SDimitry Andric};
260b57cec5SDimitry Andric
270b57cec5SDimitry Andricenum class launch
280b57cec5SDimitry Andric{
290b57cec5SDimitry Andric    async = 1,
300b57cec5SDimitry Andric    deferred = 2,
310b57cec5SDimitry Andric    any = async | deferred
320b57cec5SDimitry Andric};
330b57cec5SDimitry Andric
340b57cec5SDimitry Andricenum class future_status
350b57cec5SDimitry Andric{
360b57cec5SDimitry Andric    ready,
370b57cec5SDimitry Andric    timeout,
380b57cec5SDimitry Andric    deferred
390b57cec5SDimitry Andric};
400b57cec5SDimitry Andric
410b57cec5SDimitry Andrictemplate <> struct is_error_code_enum<future_errc> : public true_type { };
420b57cec5SDimitry Andricerror_code make_error_code(future_errc e) noexcept;
430b57cec5SDimitry Andricerror_condition make_error_condition(future_errc e) noexcept;
440b57cec5SDimitry Andric
450b57cec5SDimitry Andricconst error_category& future_category() noexcept;
460b57cec5SDimitry Andric
470b57cec5SDimitry Andricclass future_error
480b57cec5SDimitry Andric    : public logic_error
490b57cec5SDimitry Andric{
500b57cec5SDimitry Andricpublic:
510b57cec5SDimitry Andric    future_error(error_code ec);  // exposition only
520b57cec5SDimitry Andric    explicit future_error(future_errc); // C++17
530b57cec5SDimitry Andric    const error_code& code() const noexcept;
540b57cec5SDimitry Andric    const char*       what() const noexcept;
550b57cec5SDimitry Andric};
560b57cec5SDimitry Andric
570b57cec5SDimitry Andrictemplate <class R>
580b57cec5SDimitry Andricclass promise
590b57cec5SDimitry Andric{
600b57cec5SDimitry Andricpublic:
610b57cec5SDimitry Andric    promise();
620b57cec5SDimitry Andric    template <class Allocator>
630b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
640b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
650b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
660b57cec5SDimitry Andric    ~promise();
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric    // assignment
690b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
700b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
710b57cec5SDimitry Andric    void swap(promise& other) noexcept;
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric    // retrieving the result
740b57cec5SDimitry Andric    future<R> get_future();
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric    // setting the result
770b57cec5SDimitry Andric    void set_value(const R& r);
780b57cec5SDimitry Andric    void set_value(R&& r);
790b57cec5SDimitry Andric    void set_exception(exception_ptr p);
800b57cec5SDimitry Andric
810b57cec5SDimitry Andric    // setting the result with deferred notification
820b57cec5SDimitry Andric    void set_value_at_thread_exit(const R& r);
830b57cec5SDimitry Andric    void set_value_at_thread_exit(R&& r);
840b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
850b57cec5SDimitry Andric};
860b57cec5SDimitry Andric
870b57cec5SDimitry Andrictemplate <class R>
880b57cec5SDimitry Andricclass promise<R&>
890b57cec5SDimitry Andric{
900b57cec5SDimitry Andricpublic:
910b57cec5SDimitry Andric    promise();
920b57cec5SDimitry Andric    template <class Allocator>
930b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
940b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
950b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
960b57cec5SDimitry Andric    ~promise();
970b57cec5SDimitry Andric
980b57cec5SDimitry Andric    // assignment
990b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
1000b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
1010b57cec5SDimitry Andric    void swap(promise& other) noexcept;
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andric    // retrieving the result
1040b57cec5SDimitry Andric    future<R&> get_future();
1050b57cec5SDimitry Andric
1060b57cec5SDimitry Andric    // setting the result
1070b57cec5SDimitry Andric    void set_value(R& r);
1080b57cec5SDimitry Andric    void set_exception(exception_ptr p);
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric    // setting the result with deferred notification
1110b57cec5SDimitry Andric    void set_value_at_thread_exit(R&);
1120b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
1130b57cec5SDimitry Andric};
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andrictemplate <>
1160b57cec5SDimitry Andricclass promise<void>
1170b57cec5SDimitry Andric{
1180b57cec5SDimitry Andricpublic:
1190b57cec5SDimitry Andric    promise();
1200b57cec5SDimitry Andric    template <class Allocator>
1210b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
1220b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
1230b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
1240b57cec5SDimitry Andric    ~promise();
1250b57cec5SDimitry Andric
1260b57cec5SDimitry Andric    // assignment
1270b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
1280b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
1290b57cec5SDimitry Andric    void swap(promise& other) noexcept;
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric    // retrieving the result
1320b57cec5SDimitry Andric    future<void> get_future();
1330b57cec5SDimitry Andric
1340b57cec5SDimitry Andric    // setting the result
1350b57cec5SDimitry Andric    void set_value();
1360b57cec5SDimitry Andric    void set_exception(exception_ptr p);
1370b57cec5SDimitry Andric
1380b57cec5SDimitry Andric    // setting the result with deferred notification
1390b57cec5SDimitry Andric    void set_value_at_thread_exit();
1400b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
1410b57cec5SDimitry Andric};
1420b57cec5SDimitry Andric
1430b57cec5SDimitry Andrictemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
1440b57cec5SDimitry Andric
1450b57cec5SDimitry Andrictemplate <class R, class Alloc>
1460b57cec5SDimitry Andric    struct uses_allocator<promise<R>, Alloc> : public true_type {};
1470b57cec5SDimitry Andric
1480b57cec5SDimitry Andrictemplate <class R>
1490b57cec5SDimitry Andricclass future
1500b57cec5SDimitry Andric{
1510b57cec5SDimitry Andricpublic:
1520b57cec5SDimitry Andric    future() noexcept;
1530b57cec5SDimitry Andric    future(future&&) noexcept;
1540b57cec5SDimitry Andric    future(const future& rhs) = delete;
1550b57cec5SDimitry Andric    ~future();
1560b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
1570b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
1580b57cec5SDimitry Andric    shared_future<R> share() noexcept;
1590b57cec5SDimitry Andric
1600b57cec5SDimitry Andric    // retrieving the value
1610b57cec5SDimitry Andric    R get();
1620b57cec5SDimitry Andric
1630b57cec5SDimitry Andric    // functions to check state
1640b57cec5SDimitry Andric    bool valid() const noexcept;
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andric    void wait() const;
1670b57cec5SDimitry Andric    template <class Rep, class Period>
1680b57cec5SDimitry Andric        future_status
1690b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
1700b57cec5SDimitry Andric    template <class Clock, class Duration>
1710b57cec5SDimitry Andric        future_status
1720b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
1730b57cec5SDimitry Andric};
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andrictemplate <class R>
1760b57cec5SDimitry Andricclass future<R&>
1770b57cec5SDimitry Andric{
1780b57cec5SDimitry Andricpublic:
1790b57cec5SDimitry Andric    future() noexcept;
1800b57cec5SDimitry Andric    future(future&&) noexcept;
1810b57cec5SDimitry Andric    future(const future& rhs) = delete;
1820b57cec5SDimitry Andric    ~future();
1830b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
1840b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
1850b57cec5SDimitry Andric    shared_future<R&> share() noexcept;
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric    // retrieving the value
1880b57cec5SDimitry Andric    R& get();
1890b57cec5SDimitry Andric
1900b57cec5SDimitry Andric    // functions to check state
1910b57cec5SDimitry Andric    bool valid() const noexcept;
1920b57cec5SDimitry Andric
1930b57cec5SDimitry Andric    void wait() const;
1940b57cec5SDimitry Andric    template <class Rep, class Period>
1950b57cec5SDimitry Andric        future_status
1960b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
1970b57cec5SDimitry Andric    template <class Clock, class Duration>
1980b57cec5SDimitry Andric        future_status
1990b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2000b57cec5SDimitry Andric};
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andrictemplate <>
2030b57cec5SDimitry Andricclass future<void>
2040b57cec5SDimitry Andric{
2050b57cec5SDimitry Andricpublic:
2060b57cec5SDimitry Andric    future() noexcept;
2070b57cec5SDimitry Andric    future(future&&) noexcept;
2080b57cec5SDimitry Andric    future(const future& rhs) = delete;
2090b57cec5SDimitry Andric    ~future();
2100b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
2110b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
2120b57cec5SDimitry Andric    shared_future<void> share() noexcept;
2130b57cec5SDimitry Andric
2140b57cec5SDimitry Andric    // retrieving the value
2150b57cec5SDimitry Andric    void get();
2160b57cec5SDimitry Andric
2170b57cec5SDimitry Andric    // functions to check state
2180b57cec5SDimitry Andric    bool valid() const noexcept;
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andric    void wait() const;
2210b57cec5SDimitry Andric    template <class Rep, class Period>
2220b57cec5SDimitry Andric        future_status
2230b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2240b57cec5SDimitry Andric    template <class Clock, class Duration>
2250b57cec5SDimitry Andric        future_status
2260b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2270b57cec5SDimitry Andric};
2280b57cec5SDimitry Andric
2290b57cec5SDimitry Andrictemplate <class R>
2300b57cec5SDimitry Andricclass shared_future
2310b57cec5SDimitry Andric{
2320b57cec5SDimitry Andricpublic:
2330b57cec5SDimitry Andric    shared_future() noexcept;
2340b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2350b57cec5SDimitry Andric    shared_future(future<R>&&) noexcept;
2360b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2370b57cec5SDimitry Andric    ~shared_future();
2380b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2390b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2400b57cec5SDimitry Andric
2410b57cec5SDimitry Andric    // retrieving the value
2420b57cec5SDimitry Andric    const R& get() const;
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andric    // functions to check state
2450b57cec5SDimitry Andric    bool valid() const noexcept;
2460b57cec5SDimitry Andric
2470b57cec5SDimitry Andric    void wait() const;
2480b57cec5SDimitry Andric    template <class Rep, class Period>
2490b57cec5SDimitry Andric        future_status
2500b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2510b57cec5SDimitry Andric    template <class Clock, class Duration>
2520b57cec5SDimitry Andric        future_status
2530b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2540b57cec5SDimitry Andric};
2550b57cec5SDimitry Andric
2560b57cec5SDimitry Andrictemplate <class R>
2570b57cec5SDimitry Andricclass shared_future<R&>
2580b57cec5SDimitry Andric{
2590b57cec5SDimitry Andricpublic:
2600b57cec5SDimitry Andric    shared_future() noexcept;
2610b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2620b57cec5SDimitry Andric    shared_future(future<R&>&&) noexcept;
2630b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2640b57cec5SDimitry Andric    ~shared_future();
2650b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2660b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2670b57cec5SDimitry Andric
2680b57cec5SDimitry Andric    // retrieving the value
2690b57cec5SDimitry Andric    R& get() const;
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andric    // functions to check state
2720b57cec5SDimitry Andric    bool valid() const noexcept;
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andric    void wait() const;
2750b57cec5SDimitry Andric    template <class Rep, class Period>
2760b57cec5SDimitry Andric        future_status
2770b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2780b57cec5SDimitry Andric    template <class Clock, class Duration>
2790b57cec5SDimitry Andric        future_status
2800b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2810b57cec5SDimitry Andric};
2820b57cec5SDimitry Andric
2830b57cec5SDimitry Andrictemplate <>
2840b57cec5SDimitry Andricclass shared_future<void>
2850b57cec5SDimitry Andric{
2860b57cec5SDimitry Andricpublic:
2870b57cec5SDimitry Andric    shared_future() noexcept;
2880b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2890b57cec5SDimitry Andric    shared_future(future<void>&&) noexcept;
2900b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2910b57cec5SDimitry Andric    ~shared_future();
2920b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2930b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2940b57cec5SDimitry Andric
2950b57cec5SDimitry Andric    // retrieving the value
2960b57cec5SDimitry Andric    void get() const;
2970b57cec5SDimitry Andric
2980b57cec5SDimitry Andric    // functions to check state
2990b57cec5SDimitry Andric    bool valid() const noexcept;
3000b57cec5SDimitry Andric
3010b57cec5SDimitry Andric    void wait() const;
3020b57cec5SDimitry Andric    template <class Rep, class Period>
3030b57cec5SDimitry Andric        future_status
3040b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
3050b57cec5SDimitry Andric    template <class Clock, class Duration>
3060b57cec5SDimitry Andric        future_status
3070b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
3080b57cec5SDimitry Andric};
3090b57cec5SDimitry Andric
3100b57cec5SDimitry Andrictemplate <class F, class... Args>
3110b57cec5SDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
3120b57cec5SDimitry Andric  async(F&& f, Args&&... args);
3130b57cec5SDimitry Andric
3140b57cec5SDimitry Andrictemplate <class F, class... Args>
3150b57cec5SDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
3160b57cec5SDimitry Andric  async(launch policy, F&& f, Args&&... args);
3170b57cec5SDimitry Andric
3180b57cec5SDimitry Andrictemplate <class> class packaged_task; // undefined
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andrictemplate <class R, class... ArgTypes>
3210b57cec5SDimitry Andricclass packaged_task<R(ArgTypes...)>
3220b57cec5SDimitry Andric{
3230b57cec5SDimitry Andricpublic:
3240b57cec5SDimitry Andric    typedef R result_type; // extension
3250b57cec5SDimitry Andric
3260b57cec5SDimitry Andric    // construction and destruction
3270b57cec5SDimitry Andric    packaged_task() noexcept;
3280b57cec5SDimitry Andric    template <class F>
3290b57cec5SDimitry Andric        explicit packaged_task(F&& f);
3300b57cec5SDimitry Andric    template <class F, class Allocator>
3310b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const Allocator& a, F&& f);
3320b57cec5SDimitry Andric    ~packaged_task();
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andric    // no copy
3350b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
3360b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric    // move support
3390b57cec5SDimitry Andric    packaged_task(packaged_task&& other) noexcept;
3400b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& other) noexcept;
3410b57cec5SDimitry Andric    void swap(packaged_task& other) noexcept;
3420b57cec5SDimitry Andric
3430b57cec5SDimitry Andric    bool valid() const noexcept;
3440b57cec5SDimitry Andric
3450b57cec5SDimitry Andric    // result retrieval
3460b57cec5SDimitry Andric    future<R> get_future();
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andric    // execution
3490b57cec5SDimitry Andric    void operator()(ArgTypes... );
3500b57cec5SDimitry Andric    void make_ready_at_thread_exit(ArgTypes...);
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andric    void reset();
3530b57cec5SDimitry Andric};
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andrictemplate <class R>
3560b57cec5SDimitry Andric  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andrictemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andric}  // std
3610b57cec5SDimitry Andric
3620b57cec5SDimitry Andric*/
3630b57cec5SDimitry Andric
3640b57cec5SDimitry Andric#include <__config>
3650b57cec5SDimitry Andric#include <system_error>
3660b57cec5SDimitry Andric#include <memory>
3670b57cec5SDimitry Andric#include <chrono>
3680b57cec5SDimitry Andric#include <exception>
3690b57cec5SDimitry Andric#include <mutex>
3700b57cec5SDimitry Andric#include <thread>
3710b57cec5SDimitry Andric
3720b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3730b57cec5SDimitry Andric#pragma GCC system_header
3740b57cec5SDimitry Andric#endif
3750b57cec5SDimitry Andric
3760b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
3770b57cec5SDimitry Andric#error <future> is not supported on this single threaded system
3780b57cec5SDimitry Andric#else // !_LIBCPP_HAS_NO_THREADS
3790b57cec5SDimitry Andric
3800b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andric//enum class future_errc
3830b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
3840b57cec5SDimitry Andric{
3850b57cec5SDimitry Andric    future_already_retrieved = 1,
3860b57cec5SDimitry Andric    promise_already_satisfied,
3870b57cec5SDimitry Andric    no_state,
3880b57cec5SDimitry Andric    broken_promise
3890b57cec5SDimitry Andric};
3900b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andrictemplate <>
3930b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
3960b57cec5SDimitry Andrictemplate <>
3970b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
3980b57cec5SDimitry Andric#endif
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric//enum class launch
4010b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(launch)
4020b57cec5SDimitry Andric{
4030b57cec5SDimitry Andric    async = 1,
4040b57cec5SDimitry Andric    deferred = 2,
4050b57cec5SDimitry Andric    any = async | deferred
4060b57cec5SDimitry Andric};
4070b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
4080b57cec5SDimitry Andric
4090b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andrictypedef underlying_type<launch>::type __launch_underlying_type;
4120b57cec5SDimitry Andric
4130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4140b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
4150b57cec5SDimitry Andriclaunch
4160b57cec5SDimitry Andricoperator&(launch __x, launch __y)
4170b57cec5SDimitry Andric{
4180b57cec5SDimitry Andric    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
4190b57cec5SDimitry Andric                               static_cast<__launch_underlying_type>(__y));
4200b57cec5SDimitry Andric}
4210b57cec5SDimitry Andric
4220b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4230b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
4240b57cec5SDimitry Andriclaunch
4250b57cec5SDimitry Andricoperator|(launch __x, launch __y)
4260b57cec5SDimitry Andric{
4270b57cec5SDimitry Andric    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
4280b57cec5SDimitry Andric                               static_cast<__launch_underlying_type>(__y));
4290b57cec5SDimitry Andric}
4300b57cec5SDimitry Andric
4310b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4320b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
4330b57cec5SDimitry Andriclaunch
4340b57cec5SDimitry Andricoperator^(launch __x, launch __y)
4350b57cec5SDimitry Andric{
4360b57cec5SDimitry Andric    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
4370b57cec5SDimitry Andric                               static_cast<__launch_underlying_type>(__y));
4380b57cec5SDimitry Andric}
4390b57cec5SDimitry Andric
4400b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4410b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
4420b57cec5SDimitry Andriclaunch
4430b57cec5SDimitry Andricoperator~(launch __x)
4440b57cec5SDimitry Andric{
4450b57cec5SDimitry Andric    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
4460b57cec5SDimitry Andric}
4470b57cec5SDimitry Andric
4480b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4490b57cec5SDimitry Andriclaunch&
4500b57cec5SDimitry Andricoperator&=(launch& __x, launch __y)
4510b57cec5SDimitry Andric{
4520b57cec5SDimitry Andric    __x = __x & __y; return __x;
4530b57cec5SDimitry Andric}
4540b57cec5SDimitry Andric
4550b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4560b57cec5SDimitry Andriclaunch&
4570b57cec5SDimitry Andricoperator|=(launch& __x, launch __y)
4580b57cec5SDimitry Andric{
4590b57cec5SDimitry Andric    __x = __x | __y; return __x;
4600b57cec5SDimitry Andric}
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4630b57cec5SDimitry Andriclaunch&
4640b57cec5SDimitry Andricoperator^=(launch& __x, launch __y)
4650b57cec5SDimitry Andric{
4660b57cec5SDimitry Andric    __x = __x ^ __y; return __x;
4670b57cec5SDimitry Andric}
4680b57cec5SDimitry Andric
4690b57cec5SDimitry Andric#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS
4700b57cec5SDimitry Andric
4710b57cec5SDimitry Andric//enum class future_status
4720b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_status)
4730b57cec5SDimitry Andric{
4740b57cec5SDimitry Andric    ready,
4750b57cec5SDimitry Andric    timeout,
4760b57cec5SDimitry Andric    deferred
4770b57cec5SDimitry Andric};
4780b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
4790b57cec5SDimitry Andric
4800b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
4810b57cec5SDimitry Andricconst error_category& future_category() _NOEXCEPT;
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4840b57cec5SDimitry Andricerror_code
4850b57cec5SDimitry Andricmake_error_code(future_errc __e) _NOEXCEPT
4860b57cec5SDimitry Andric{
4870b57cec5SDimitry Andric    return error_code(static_cast<int>(__e), future_category());
4880b57cec5SDimitry Andric}
4890b57cec5SDimitry Andric
4900b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4910b57cec5SDimitry Andricerror_condition
4920b57cec5SDimitry Andricmake_error_condition(future_errc __e) _NOEXCEPT
4930b57cec5SDimitry Andric{
4940b57cec5SDimitry Andric    return error_condition(static_cast<int>(__e), future_category());
4950b57cec5SDimitry Andric}
4960b57cec5SDimitry Andric
4970b57cec5SDimitry Andricclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
4980b57cec5SDimitry Andric    : public logic_error
4990b57cec5SDimitry Andric{
5000b57cec5SDimitry Andric    error_code __ec_;
5010b57cec5SDimitry Andricpublic:
5020b57cec5SDimitry Andric    future_error(error_code __ec);
5030b57cec5SDimitry Andric#if _LIBCPP_STD_VERS > 14
5040b57cec5SDimitry Andric    explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
5050b57cec5SDimitry Andric#endif
5060b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5070b57cec5SDimitry Andric    const error_code& code() const _NOEXCEPT {return __ec_;}
5080b57cec5SDimitry Andric
509*9ec406dcSDimitry Andric    future_error(const future_error&) _NOEXCEPT = default;
5100b57cec5SDimitry Andric    virtual ~future_error() _NOEXCEPT;
5110b57cec5SDimitry Andric};
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
5140b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
5150b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_FUTURE_ERROR
5160b57cec5SDimitry Andric#endif
5170b57cec5SDimitry Andricvoid __throw_future_error(future_errc _Ev)
5180b57cec5SDimitry Andric{
5190b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
5200b57cec5SDimitry Andric    throw future_error(make_error_code(_Ev));
5210b57cec5SDimitry Andric#else
5220b57cec5SDimitry Andric    ((void)_Ev);
5230b57cec5SDimitry Andric    _VSTD::abort();
5240b57cec5SDimitry Andric#endif
5250b57cec5SDimitry Andric}
5260b57cec5SDimitry Andric
5270b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
5280b57cec5SDimitry Andric    : public __shared_count
5290b57cec5SDimitry Andric{
5300b57cec5SDimitry Andricprotected:
5310b57cec5SDimitry Andric    exception_ptr __exception_;
5320b57cec5SDimitry Andric    mutable mutex __mut_;
5330b57cec5SDimitry Andric    mutable condition_variable __cv_;
5340b57cec5SDimitry Andric    unsigned __state_;
5350b57cec5SDimitry Andric
5360b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
5370b57cec5SDimitry Andric    void __sub_wait(unique_lock<mutex>& __lk);
5380b57cec5SDimitry Andricpublic:
5390b57cec5SDimitry Andric    enum
5400b57cec5SDimitry Andric    {
5410b57cec5SDimitry Andric        __constructed = 1,
5420b57cec5SDimitry Andric        __future_attached = 2,
5430b57cec5SDimitry Andric        ready = 4,
5440b57cec5SDimitry Andric        deferred = 8
5450b57cec5SDimitry Andric    };
5460b57cec5SDimitry Andric
5470b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5480b57cec5SDimitry Andric    __assoc_sub_state() : __state_(0) {}
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5510b57cec5SDimitry Andric    bool __has_value() const
5520b57cec5SDimitry Andric        {return (__state_ & __constructed) || (__exception_ != nullptr);}
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5550b57cec5SDimitry Andric    void __attach_future() {
5560b57cec5SDimitry Andric        lock_guard<mutex> __lk(__mut_);
5570b57cec5SDimitry Andric        bool __has_future_attached = (__state_ & __future_attached) != 0;
5580b57cec5SDimitry Andric        if (__has_future_attached)
5590b57cec5SDimitry Andric            __throw_future_error(future_errc::future_already_retrieved);
5600b57cec5SDimitry Andric        this->__add_shared();
5610b57cec5SDimitry Andric        __state_ |= __future_attached;
5620b57cec5SDimitry Andric    }
5630b57cec5SDimitry Andric
5640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5650b57cec5SDimitry Andric    void __set_deferred() {__state_ |= deferred;}
5660b57cec5SDimitry Andric
5670b57cec5SDimitry Andric    void __make_ready();
5680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5690b57cec5SDimitry Andric    bool __is_ready() const {return (__state_ & ready) != 0;}
5700b57cec5SDimitry Andric
5710b57cec5SDimitry Andric    void set_value();
5720b57cec5SDimitry Andric    void set_value_at_thread_exit();
5730b57cec5SDimitry Andric
5740b57cec5SDimitry Andric    void set_exception(exception_ptr __p);
5750b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr __p);
5760b57cec5SDimitry Andric
5770b57cec5SDimitry Andric    void copy();
5780b57cec5SDimitry Andric
5790b57cec5SDimitry Andric    void wait();
5800b57cec5SDimitry Andric    template <class _Rep, class _Period>
5810b57cec5SDimitry Andric        future_status
5820b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
5830b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
5840b57cec5SDimitry Andric    template <class _Clock, class _Duration>
5850b57cec5SDimitry Andric        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
5860b57cec5SDimitry Andric        future_status
5870b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andric    virtual void __execute();
5900b57cec5SDimitry Andric};
5910b57cec5SDimitry Andric
5920b57cec5SDimitry Andrictemplate <class _Clock, class _Duration>
5930b57cec5SDimitry Andricfuture_status
5940b57cec5SDimitry Andric__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
5950b57cec5SDimitry Andric{
5960b57cec5SDimitry Andric    unique_lock<mutex> __lk(__mut_);
5970b57cec5SDimitry Andric    if (__state_ & deferred)
5980b57cec5SDimitry Andric        return future_status::deferred;
5990b57cec5SDimitry Andric    while (!(__state_ & ready) && _Clock::now() < __abs_time)
6000b57cec5SDimitry Andric        __cv_.wait_until(__lk, __abs_time);
6010b57cec5SDimitry Andric    if (__state_ & ready)
6020b57cec5SDimitry Andric        return future_status::ready;
6030b57cec5SDimitry Andric    return future_status::timeout;
6040b57cec5SDimitry Andric}
6050b57cec5SDimitry Andric
6060b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
6070b57cec5SDimitry Andricinline
6080b57cec5SDimitry Andricfuture_status
6090b57cec5SDimitry Andric__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
6100b57cec5SDimitry Andric{
6110b57cec5SDimitry Andric    return wait_until(chrono::steady_clock::now() + __rel_time);
6120b57cec5SDimitry Andric}
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andrictemplate <class _Rp>
615480093f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
6160b57cec5SDimitry Andric    : public __assoc_sub_state
6170b57cec5SDimitry Andric{
6180b57cec5SDimitry Andric    typedef __assoc_sub_state base;
6190b57cec5SDimitry Andric    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
6200b57cec5SDimitry Andricprotected:
6210b57cec5SDimitry Andric    _Up __value_;
6220b57cec5SDimitry Andric
6230b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
6240b57cec5SDimitry Andricpublic:
6250b57cec5SDimitry Andric
6260b57cec5SDimitry Andric    template <class _Arg>
6270b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
6280b57cec5SDimitry Andric        void set_value(_Arg&& __arg);
6290b57cec5SDimitry Andric#else
6300b57cec5SDimitry Andric        void set_value(_Arg& __arg);
6310b57cec5SDimitry Andric#endif
6320b57cec5SDimitry Andric
6330b57cec5SDimitry Andric    template <class _Arg>
6340b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
6350b57cec5SDimitry Andric        void set_value_at_thread_exit(_Arg&& __arg);
6360b57cec5SDimitry Andric#else
6370b57cec5SDimitry Andric        void set_value_at_thread_exit(_Arg& __arg);
6380b57cec5SDimitry Andric#endif
6390b57cec5SDimitry Andric
6400b57cec5SDimitry Andric    _Rp move();
6410b57cec5SDimitry Andric    typename add_lvalue_reference<_Rp>::type copy();
6420b57cec5SDimitry Andric};
6430b57cec5SDimitry Andric
6440b57cec5SDimitry Andrictemplate <class _Rp>
6450b57cec5SDimitry Andricvoid
6460b57cec5SDimitry Andric__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
6470b57cec5SDimitry Andric{
6480b57cec5SDimitry Andric    if (this->__state_ & base::__constructed)
6490b57cec5SDimitry Andric        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
6500b57cec5SDimitry Andric    delete this;
6510b57cec5SDimitry Andric}
6520b57cec5SDimitry Andric
6530b57cec5SDimitry Andrictemplate <class _Rp>
6540b57cec5SDimitry Andrictemplate <class _Arg>
6550b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_FUTURE
6560b57cec5SDimitry Andricvoid
6570b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
6580b57cec5SDimitry Andric__assoc_state<_Rp>::set_value(_Arg&& __arg)
6590b57cec5SDimitry Andric#else
6600b57cec5SDimitry Andric__assoc_state<_Rp>::set_value(_Arg& __arg)
6610b57cec5SDimitry Andric#endif
6620b57cec5SDimitry Andric{
6630b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
6640b57cec5SDimitry Andric    if (this->__has_value())
6650b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
6660b57cec5SDimitry Andric    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
6670b57cec5SDimitry Andric    this->__state_ |= base::__constructed | base::ready;
6680b57cec5SDimitry Andric    __cv_.notify_all();
6690b57cec5SDimitry Andric}
6700b57cec5SDimitry Andric
6710b57cec5SDimitry Andrictemplate <class _Rp>
6720b57cec5SDimitry Andrictemplate <class _Arg>
6730b57cec5SDimitry Andricvoid
6740b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
6750b57cec5SDimitry Andric__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
6760b57cec5SDimitry Andric#else
6770b57cec5SDimitry Andric__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
6780b57cec5SDimitry Andric#endif
6790b57cec5SDimitry Andric{
6800b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
6810b57cec5SDimitry Andric    if (this->__has_value())
6820b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
6830b57cec5SDimitry Andric    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
6840b57cec5SDimitry Andric    this->__state_ |= base::__constructed;
6850b57cec5SDimitry Andric    __thread_local_data()->__make_ready_at_thread_exit(this);
6860b57cec5SDimitry Andric}
6870b57cec5SDimitry Andric
6880b57cec5SDimitry Andrictemplate <class _Rp>
6890b57cec5SDimitry Andric_Rp
6900b57cec5SDimitry Andric__assoc_state<_Rp>::move()
6910b57cec5SDimitry Andric{
6920b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
6930b57cec5SDimitry Andric    this->__sub_wait(__lk);
6940b57cec5SDimitry Andric    if (this->__exception_ != nullptr)
6950b57cec5SDimitry Andric        rethrow_exception(this->__exception_);
6960b57cec5SDimitry Andric    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
6970b57cec5SDimitry Andric}
6980b57cec5SDimitry Andric
6990b57cec5SDimitry Andrictemplate <class _Rp>
7000b57cec5SDimitry Andrictypename add_lvalue_reference<_Rp>::type
7010b57cec5SDimitry Andric__assoc_state<_Rp>::copy()
7020b57cec5SDimitry Andric{
7030b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
7040b57cec5SDimitry Andric    this->__sub_wait(__lk);
7050b57cec5SDimitry Andric    if (this->__exception_ != nullptr)
7060b57cec5SDimitry Andric        rethrow_exception(this->__exception_);
7070b57cec5SDimitry Andric    return *reinterpret_cast<_Rp*>(&__value_);
7080b57cec5SDimitry Andric}
7090b57cec5SDimitry Andric
7100b57cec5SDimitry Andrictemplate <class _Rp>
7110b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
7120b57cec5SDimitry Andric    : public __assoc_sub_state
7130b57cec5SDimitry Andric{
7140b57cec5SDimitry Andric    typedef __assoc_sub_state base;
7150b57cec5SDimitry Andric    typedef _Rp* _Up;
7160b57cec5SDimitry Andricprotected:
7170b57cec5SDimitry Andric    _Up __value_;
7180b57cec5SDimitry Andric
7190b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
7200b57cec5SDimitry Andricpublic:
7210b57cec5SDimitry Andric
7220b57cec5SDimitry Andric    void set_value(_Rp& __arg);
7230b57cec5SDimitry Andric    void set_value_at_thread_exit(_Rp& __arg);
7240b57cec5SDimitry Andric
7250b57cec5SDimitry Andric    _Rp& copy();
7260b57cec5SDimitry Andric};
7270b57cec5SDimitry Andric
7280b57cec5SDimitry Andrictemplate <class _Rp>
7290b57cec5SDimitry Andricvoid
7300b57cec5SDimitry Andric__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
7310b57cec5SDimitry Andric{
7320b57cec5SDimitry Andric    delete this;
7330b57cec5SDimitry Andric}
7340b57cec5SDimitry Andric
7350b57cec5SDimitry Andrictemplate <class _Rp>
7360b57cec5SDimitry Andricvoid
7370b57cec5SDimitry Andric__assoc_state<_Rp&>::set_value(_Rp& __arg)
7380b57cec5SDimitry Andric{
7390b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
7400b57cec5SDimitry Andric    if (this->__has_value())
7410b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
7420b57cec5SDimitry Andric    __value_ = _VSTD::addressof(__arg);
7430b57cec5SDimitry Andric    this->__state_ |= base::__constructed | base::ready;
7440b57cec5SDimitry Andric    __cv_.notify_all();
7450b57cec5SDimitry Andric}
7460b57cec5SDimitry Andric
7470b57cec5SDimitry Andrictemplate <class _Rp>
7480b57cec5SDimitry Andricvoid
7490b57cec5SDimitry Andric__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
7500b57cec5SDimitry Andric{
7510b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
7520b57cec5SDimitry Andric    if (this->__has_value())
7530b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
7540b57cec5SDimitry Andric    __value_ = _VSTD::addressof(__arg);
7550b57cec5SDimitry Andric    this->__state_ |= base::__constructed;
7560b57cec5SDimitry Andric    __thread_local_data()->__make_ready_at_thread_exit(this);
7570b57cec5SDimitry Andric}
7580b57cec5SDimitry Andric
7590b57cec5SDimitry Andrictemplate <class _Rp>
7600b57cec5SDimitry Andric_Rp&
7610b57cec5SDimitry Andric__assoc_state<_Rp&>::copy()
7620b57cec5SDimitry Andric{
7630b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
7640b57cec5SDimitry Andric    this->__sub_wait(__lk);
7650b57cec5SDimitry Andric    if (this->__exception_ != nullptr)
7660b57cec5SDimitry Andric        rethrow_exception(this->__exception_);
7670b57cec5SDimitry Andric    return *__value_;
7680b57cec5SDimitry Andric}
7690b57cec5SDimitry Andric
7700b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
7710b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
7720b57cec5SDimitry Andric    : public __assoc_state<_Rp>
7730b57cec5SDimitry Andric{
7740b57cec5SDimitry Andric    typedef __assoc_state<_Rp> base;
7750b57cec5SDimitry Andric    _Alloc __alloc_;
7760b57cec5SDimitry Andric
7770b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
7780b57cec5SDimitry Andricpublic:
7790b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
7800b57cec5SDimitry Andric    explicit __assoc_state_alloc(const _Alloc& __a)
7810b57cec5SDimitry Andric        : __alloc_(__a) {}
7820b57cec5SDimitry Andric};
7830b57cec5SDimitry Andric
7840b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
7850b57cec5SDimitry Andricvoid
7860b57cec5SDimitry Andric__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
7870b57cec5SDimitry Andric{
7880b57cec5SDimitry Andric    if (this->__state_ & base::__constructed)
7890b57cec5SDimitry Andric        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
7900b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
7910b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
7920b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7930b57cec5SDimitry Andric    _Al __a(__alloc_);
7940b57cec5SDimitry Andric    this->~__assoc_state_alloc();
7950b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
7960b57cec5SDimitry Andric}
7970b57cec5SDimitry Andric
7980b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
7990b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
8000b57cec5SDimitry Andric    : public __assoc_state<_Rp&>
8010b57cec5SDimitry Andric{
8020b57cec5SDimitry Andric    typedef __assoc_state<_Rp&> base;
8030b57cec5SDimitry Andric    _Alloc __alloc_;
8040b57cec5SDimitry Andric
8050b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
8060b57cec5SDimitry Andricpublic:
8070b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
8080b57cec5SDimitry Andric    explicit __assoc_state_alloc(const _Alloc& __a)
8090b57cec5SDimitry Andric        : __alloc_(__a) {}
8100b57cec5SDimitry Andric};
8110b57cec5SDimitry Andric
8120b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
8130b57cec5SDimitry Andricvoid
8140b57cec5SDimitry Andric__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
8150b57cec5SDimitry Andric{
8160b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
8170b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
8180b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
8190b57cec5SDimitry Andric    _Al __a(__alloc_);
8200b57cec5SDimitry Andric    this->~__assoc_state_alloc();
8210b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
8220b57cec5SDimitry Andric}
8230b57cec5SDimitry Andric
8240b57cec5SDimitry Andrictemplate <class _Alloc>
8250b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
8260b57cec5SDimitry Andric    : public __assoc_sub_state
8270b57cec5SDimitry Andric{
8280b57cec5SDimitry Andric    typedef __assoc_sub_state base;
8290b57cec5SDimitry Andric    _Alloc __alloc_;
8300b57cec5SDimitry Andric
8310b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
8320b57cec5SDimitry Andricpublic:
8330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
8340b57cec5SDimitry Andric    explicit __assoc_sub_state_alloc(const _Alloc& __a)
8350b57cec5SDimitry Andric        : __alloc_(__a) {}
8360b57cec5SDimitry Andric};
8370b57cec5SDimitry Andric
8380b57cec5SDimitry Andrictemplate <class _Alloc>
8390b57cec5SDimitry Andricvoid
8400b57cec5SDimitry Andric__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
8410b57cec5SDimitry Andric{
8420b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
8430b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
8440b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
8450b57cec5SDimitry Andric    _Al __a(__alloc_);
8460b57cec5SDimitry Andric    this->~__assoc_sub_state_alloc();
8470b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
8480b57cec5SDimitry Andric}
8490b57cec5SDimitry Andric
8500b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
8510b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
8520b57cec5SDimitry Andric    : public __assoc_state<_Rp>
8530b57cec5SDimitry Andric{
8540b57cec5SDimitry Andric    typedef __assoc_state<_Rp> base;
8550b57cec5SDimitry Andric
8560b57cec5SDimitry Andric    _Fp __func_;
8570b57cec5SDimitry Andric
8580b57cec5SDimitry Andricpublic:
8590b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
8600b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
8610b57cec5SDimitry Andric    explicit __deferred_assoc_state(_Fp&& __f);
8620b57cec5SDimitry Andric#endif
8630b57cec5SDimitry Andric
8640b57cec5SDimitry Andric    virtual void __execute();
8650b57cec5SDimitry Andric};
8660b57cec5SDimitry Andric
8670b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
8680b57cec5SDimitry Andric
8690b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
8700b57cec5SDimitry Andricinline
8710b57cec5SDimitry Andric__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
8720b57cec5SDimitry Andric    : __func_(_VSTD::forward<_Fp>(__f))
8730b57cec5SDimitry Andric{
8740b57cec5SDimitry Andric    this->__set_deferred();
8750b57cec5SDimitry Andric}
8760b57cec5SDimitry Andric
8770b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
8780b57cec5SDimitry Andric
8790b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
8800b57cec5SDimitry Andricvoid
8810b57cec5SDimitry Andric__deferred_assoc_state<_Rp, _Fp>::__execute()
8820b57cec5SDimitry Andric{
8830b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
8840b57cec5SDimitry Andric    try
8850b57cec5SDimitry Andric    {
8860b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
8870b57cec5SDimitry Andric        this->set_value(__func_());
8880b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
8890b57cec5SDimitry Andric    }
8900b57cec5SDimitry Andric    catch (...)
8910b57cec5SDimitry Andric    {
8920b57cec5SDimitry Andric        this->set_exception(current_exception());
8930b57cec5SDimitry Andric    }
8940b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
8950b57cec5SDimitry Andric}
8960b57cec5SDimitry Andric
8970b57cec5SDimitry Andrictemplate <class _Fp>
8980b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
8990b57cec5SDimitry Andric    : public __assoc_sub_state
9000b57cec5SDimitry Andric{
9010b57cec5SDimitry Andric    typedef __assoc_sub_state base;
9020b57cec5SDimitry Andric
9030b57cec5SDimitry Andric    _Fp __func_;
9040b57cec5SDimitry Andric
9050b57cec5SDimitry Andricpublic:
9060b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
9070b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
9080b57cec5SDimitry Andric    explicit __deferred_assoc_state(_Fp&& __f);
9090b57cec5SDimitry Andric#endif
9100b57cec5SDimitry Andric
9110b57cec5SDimitry Andric    virtual void __execute();
9120b57cec5SDimitry Andric};
9130b57cec5SDimitry Andric
9140b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
9150b57cec5SDimitry Andric
9160b57cec5SDimitry Andrictemplate <class _Fp>
9170b57cec5SDimitry Andricinline
9180b57cec5SDimitry Andric__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
9190b57cec5SDimitry Andric    : __func_(_VSTD::forward<_Fp>(__f))
9200b57cec5SDimitry Andric{
9210b57cec5SDimitry Andric    this->__set_deferred();
9220b57cec5SDimitry Andric}
9230b57cec5SDimitry Andric
9240b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
9250b57cec5SDimitry Andric
9260b57cec5SDimitry Andrictemplate <class _Fp>
9270b57cec5SDimitry Andricvoid
9280b57cec5SDimitry Andric__deferred_assoc_state<void, _Fp>::__execute()
9290b57cec5SDimitry Andric{
9300b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
9310b57cec5SDimitry Andric    try
9320b57cec5SDimitry Andric    {
9330b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
9340b57cec5SDimitry Andric        __func_();
9350b57cec5SDimitry Andric        this->set_value();
9360b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
9370b57cec5SDimitry Andric    }
9380b57cec5SDimitry Andric    catch (...)
9390b57cec5SDimitry Andric    {
9400b57cec5SDimitry Andric        this->set_exception(current_exception());
9410b57cec5SDimitry Andric    }
9420b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
9430b57cec5SDimitry Andric}
9440b57cec5SDimitry Andric
9450b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
9460b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
9470b57cec5SDimitry Andric    : public __assoc_state<_Rp>
9480b57cec5SDimitry Andric{
9490b57cec5SDimitry Andric    typedef __assoc_state<_Rp> base;
9500b57cec5SDimitry Andric
9510b57cec5SDimitry Andric    _Fp __func_;
9520b57cec5SDimitry Andric
9530b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
9540b57cec5SDimitry Andricpublic:
9550b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
9560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
9570b57cec5SDimitry Andric    explicit __async_assoc_state(_Fp&& __f);
9580b57cec5SDimitry Andric#endif
9590b57cec5SDimitry Andric
9600b57cec5SDimitry Andric    virtual void __execute();
9610b57cec5SDimitry Andric};
9620b57cec5SDimitry Andric
9630b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
9640b57cec5SDimitry Andric
9650b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
9660b57cec5SDimitry Andricinline
9670b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
9680b57cec5SDimitry Andric    : __func_(_VSTD::forward<_Fp>(__f))
9690b57cec5SDimitry Andric{
9700b57cec5SDimitry Andric}
9710b57cec5SDimitry Andric
9720b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
9730b57cec5SDimitry Andric
9740b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
9750b57cec5SDimitry Andricvoid
9760b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__execute()
9770b57cec5SDimitry Andric{
9780b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
9790b57cec5SDimitry Andric    try
9800b57cec5SDimitry Andric    {
9810b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
9820b57cec5SDimitry Andric        this->set_value(__func_());
9830b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
9840b57cec5SDimitry Andric    }
9850b57cec5SDimitry Andric    catch (...)
9860b57cec5SDimitry Andric    {
9870b57cec5SDimitry Andric        this->set_exception(current_exception());
9880b57cec5SDimitry Andric    }
9890b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
9900b57cec5SDimitry Andric}
9910b57cec5SDimitry Andric
9920b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
9930b57cec5SDimitry Andricvoid
9940b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
9950b57cec5SDimitry Andric{
9960b57cec5SDimitry Andric    this->wait();
9970b57cec5SDimitry Andric    base::__on_zero_shared();
9980b57cec5SDimitry Andric}
9990b57cec5SDimitry Andric
10000b57cec5SDimitry Andrictemplate <class _Fp>
10010b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
10020b57cec5SDimitry Andric    : public __assoc_sub_state
10030b57cec5SDimitry Andric{
10040b57cec5SDimitry Andric    typedef __assoc_sub_state base;
10050b57cec5SDimitry Andric
10060b57cec5SDimitry Andric    _Fp __func_;
10070b57cec5SDimitry Andric
10080b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
10090b57cec5SDimitry Andricpublic:
10100b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
10110b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
10120b57cec5SDimitry Andric    explicit __async_assoc_state(_Fp&& __f);
10130b57cec5SDimitry Andric#endif
10140b57cec5SDimitry Andric
10150b57cec5SDimitry Andric    virtual void __execute();
10160b57cec5SDimitry Andric};
10170b57cec5SDimitry Andric
10180b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
10190b57cec5SDimitry Andric
10200b57cec5SDimitry Andrictemplate <class _Fp>
10210b57cec5SDimitry Andricinline
10220b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
10230b57cec5SDimitry Andric    : __func_(_VSTD::forward<_Fp>(__f))
10240b57cec5SDimitry Andric{
10250b57cec5SDimitry Andric}
10260b57cec5SDimitry Andric
10270b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
10280b57cec5SDimitry Andric
10290b57cec5SDimitry Andrictemplate <class _Fp>
10300b57cec5SDimitry Andricvoid
10310b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__execute()
10320b57cec5SDimitry Andric{
10330b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
10340b57cec5SDimitry Andric    try
10350b57cec5SDimitry Andric    {
10360b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
10370b57cec5SDimitry Andric        __func_();
10380b57cec5SDimitry Andric        this->set_value();
10390b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
10400b57cec5SDimitry Andric    }
10410b57cec5SDimitry Andric    catch (...)
10420b57cec5SDimitry Andric    {
10430b57cec5SDimitry Andric        this->set_exception(current_exception());
10440b57cec5SDimitry Andric    }
10450b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
10460b57cec5SDimitry Andric}
10470b57cec5SDimitry Andric
10480b57cec5SDimitry Andrictemplate <class _Fp>
10490b57cec5SDimitry Andricvoid
10500b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
10510b57cec5SDimitry Andric{
10520b57cec5SDimitry Andric    this->wait();
10530b57cec5SDimitry Andric    base::__on_zero_shared();
10540b57cec5SDimitry Andric}
10550b57cec5SDimitry Andric
10560b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
10570b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
10580b57cec5SDimitry Andric
10590b57cec5SDimitry Andric// future
10600b57cec5SDimitry Andric
10610b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
10620b57cec5SDimitry Andric
10630b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1064480093f4SDimitry Andric_LIBCPP_INLINE_VISIBILITY future<_Rp>
10650b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
10660b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp&& __f);
10670b57cec5SDimitry Andric#else
10680b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp __f);
10690b57cec5SDimitry Andric#endif
10700b57cec5SDimitry Andric
10710b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1072480093f4SDimitry Andric_LIBCPP_INLINE_VISIBILITY future<_Rp>
10730b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
10740b57cec5SDimitry Andric__make_async_assoc_state(_Fp&& __f);
10750b57cec5SDimitry Andric#else
10760b57cec5SDimitry Andric__make_async_assoc_state(_Fp __f);
10770b57cec5SDimitry Andric#endif
10780b57cec5SDimitry Andric
10790b57cec5SDimitry Andrictemplate <class _Rp>
10800b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
10810b57cec5SDimitry Andric{
10820b57cec5SDimitry Andric    __assoc_state<_Rp>* __state_;
10830b57cec5SDimitry Andric
10840b57cec5SDimitry Andric    explicit future(__assoc_state<_Rp>* __state);
10850b57cec5SDimitry Andric
10860b57cec5SDimitry Andric    template <class> friend class promise;
10870b57cec5SDimitry Andric    template <class> friend class shared_future;
10880b57cec5SDimitry Andric
10890b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
10900b57cec5SDimitry Andric    template <class _R1, class _Fp>
10910b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
10920b57cec5SDimitry Andric    template <class _R1, class _Fp>
10930b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
10940b57cec5SDimitry Andric#else
10950b57cec5SDimitry Andric    template <class _R1, class _Fp>
10960b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
10970b57cec5SDimitry Andric    template <class _R1, class _Fp>
10980b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp __f);
10990b57cec5SDimitry Andric#endif
11000b57cec5SDimitry Andric
11010b57cec5SDimitry Andricpublic:
11020b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
11030b57cec5SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
11040b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
11050b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
11060b57cec5SDimitry Andric    future(future&& __rhs) _NOEXCEPT
11070b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
11080b57cec5SDimitry Andric    future(const future&) = delete;
11090b57cec5SDimitry Andric    future& operator=(const future&) = delete;
11100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
11110b57cec5SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
11120b57cec5SDimitry Andric        {
11130b57cec5SDimitry Andric            future(std::move(__rhs)).swap(*this);
11140b57cec5SDimitry Andric            return *this;
11150b57cec5SDimitry Andric        }
11160b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
11170b57cec5SDimitry Andricprivate:
11180b57cec5SDimitry Andric    future(const future&);
11190b57cec5SDimitry Andric    future& operator=(const future&);
11200b57cec5SDimitry Andricpublic:
11210b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
11220b57cec5SDimitry Andric    ~future();
11230b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
11240b57cec5SDimitry Andric    shared_future<_Rp> share() _NOEXCEPT;
11250b57cec5SDimitry Andric
11260b57cec5SDimitry Andric    // retrieving the value
11270b57cec5SDimitry Andric    _Rp get();
11280b57cec5SDimitry Andric
11290b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
11300b57cec5SDimitry Andric    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andric    // functions to check state
11330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
11340b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
11350b57cec5SDimitry Andric
11360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
11370b57cec5SDimitry Andric    void wait() const {__state_->wait();}
11380b57cec5SDimitry Andric    template <class _Rep, class _Period>
11390b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
11400b57cec5SDimitry Andric        future_status
11410b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
11420b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
11430b57cec5SDimitry Andric    template <class _Clock, class _Duration>
11440b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
11450b57cec5SDimitry Andric        future_status
11460b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
11470b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
11480b57cec5SDimitry Andric};
11490b57cec5SDimitry Andric
11500b57cec5SDimitry Andrictemplate <class _Rp>
11510b57cec5SDimitry Andricfuture<_Rp>::future(__assoc_state<_Rp>* __state)
11520b57cec5SDimitry Andric    : __state_(__state)
11530b57cec5SDimitry Andric{
11540b57cec5SDimitry Andric    __state_->__attach_future();
11550b57cec5SDimitry Andric}
11560b57cec5SDimitry Andric
11570b57cec5SDimitry Andricstruct __release_shared_count
11580b57cec5SDimitry Andric{
11590b57cec5SDimitry Andric    void operator()(__shared_count* p) {p->__release_shared();}
11600b57cec5SDimitry Andric};
11610b57cec5SDimitry Andric
11620b57cec5SDimitry Andrictemplate <class _Rp>
11630b57cec5SDimitry Andricfuture<_Rp>::~future()
11640b57cec5SDimitry Andric{
11650b57cec5SDimitry Andric    if (__state_)
11660b57cec5SDimitry Andric        __state_->__release_shared();
11670b57cec5SDimitry Andric}
11680b57cec5SDimitry Andric
11690b57cec5SDimitry Andrictemplate <class _Rp>
11700b57cec5SDimitry Andric_Rp
11710b57cec5SDimitry Andricfuture<_Rp>::get()
11720b57cec5SDimitry Andric{
11730b57cec5SDimitry Andric    unique_ptr<__shared_count, __release_shared_count> __(__state_);
11740b57cec5SDimitry Andric    __assoc_state<_Rp>* __s = __state_;
11750b57cec5SDimitry Andric    __state_ = nullptr;
11760b57cec5SDimitry Andric    return __s->move();
11770b57cec5SDimitry Andric}
11780b57cec5SDimitry Andric
11790b57cec5SDimitry Andrictemplate <class _Rp>
11800b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
11810b57cec5SDimitry Andric{
11820b57cec5SDimitry Andric    __assoc_state<_Rp&>* __state_;
11830b57cec5SDimitry Andric
11840b57cec5SDimitry Andric    explicit future(__assoc_state<_Rp&>* __state);
11850b57cec5SDimitry Andric
11860b57cec5SDimitry Andric    template <class> friend class promise;
11870b57cec5SDimitry Andric    template <class> friend class shared_future;
11880b57cec5SDimitry Andric
11890b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
11900b57cec5SDimitry Andric    template <class _R1, class _Fp>
11910b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
11920b57cec5SDimitry Andric    template <class _R1, class _Fp>
11930b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
11940b57cec5SDimitry Andric#else
11950b57cec5SDimitry Andric    template <class _R1, class _Fp>
11960b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
11970b57cec5SDimitry Andric    template <class _R1, class _Fp>
11980b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp __f);
11990b57cec5SDimitry Andric#endif
12000b57cec5SDimitry Andric
12010b57cec5SDimitry Andricpublic:
12020b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12030b57cec5SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
12040b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
12050b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12060b57cec5SDimitry Andric    future(future&& __rhs) _NOEXCEPT
12070b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
12080b57cec5SDimitry Andric    future(const future&) = delete;
12090b57cec5SDimitry Andric    future& operator=(const future&) = delete;
12100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12110b57cec5SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
12120b57cec5SDimitry Andric        {
12130b57cec5SDimitry Andric            future(std::move(__rhs)).swap(*this);
12140b57cec5SDimitry Andric            return *this;
12150b57cec5SDimitry Andric        }
12160b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
12170b57cec5SDimitry Andricprivate:
12180b57cec5SDimitry Andric    future(const future&);
12190b57cec5SDimitry Andric    future& operator=(const future&);
12200b57cec5SDimitry Andricpublic:
12210b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
12220b57cec5SDimitry Andric    ~future();
12230b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12240b57cec5SDimitry Andric    shared_future<_Rp&> share() _NOEXCEPT;
12250b57cec5SDimitry Andric
12260b57cec5SDimitry Andric    // retrieving the value
12270b57cec5SDimitry Andric    _Rp& get();
12280b57cec5SDimitry Andric
12290b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12300b57cec5SDimitry Andric    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
12310b57cec5SDimitry Andric
12320b57cec5SDimitry Andric    // functions to check state
12330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12340b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
12350b57cec5SDimitry Andric
12360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12370b57cec5SDimitry Andric    void wait() const {__state_->wait();}
12380b57cec5SDimitry Andric    template <class _Rep, class _Period>
12390b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
12400b57cec5SDimitry Andric        future_status
12410b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
12420b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
12430b57cec5SDimitry Andric    template <class _Clock, class _Duration>
12440b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
12450b57cec5SDimitry Andric        future_status
12460b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
12470b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
12480b57cec5SDimitry Andric};
12490b57cec5SDimitry Andric
12500b57cec5SDimitry Andrictemplate <class _Rp>
12510b57cec5SDimitry Andricfuture<_Rp&>::future(__assoc_state<_Rp&>* __state)
12520b57cec5SDimitry Andric    : __state_(__state)
12530b57cec5SDimitry Andric{
12540b57cec5SDimitry Andric    __state_->__attach_future();
12550b57cec5SDimitry Andric}
12560b57cec5SDimitry Andric
12570b57cec5SDimitry Andrictemplate <class _Rp>
12580b57cec5SDimitry Andricfuture<_Rp&>::~future()
12590b57cec5SDimitry Andric{
12600b57cec5SDimitry Andric    if (__state_)
12610b57cec5SDimitry Andric        __state_->__release_shared();
12620b57cec5SDimitry Andric}
12630b57cec5SDimitry Andric
12640b57cec5SDimitry Andrictemplate <class _Rp>
12650b57cec5SDimitry Andric_Rp&
12660b57cec5SDimitry Andricfuture<_Rp&>::get()
12670b57cec5SDimitry Andric{
12680b57cec5SDimitry Andric    unique_ptr<__shared_count, __release_shared_count> __(__state_);
12690b57cec5SDimitry Andric    __assoc_state<_Rp&>* __s = __state_;
12700b57cec5SDimitry Andric    __state_ = nullptr;
12710b57cec5SDimitry Andric    return __s->copy();
12720b57cec5SDimitry Andric}
12730b57cec5SDimitry Andric
12740b57cec5SDimitry Andrictemplate <>
12750b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
12760b57cec5SDimitry Andric{
12770b57cec5SDimitry Andric    __assoc_sub_state* __state_;
12780b57cec5SDimitry Andric
12790b57cec5SDimitry Andric    explicit future(__assoc_sub_state* __state);
12800b57cec5SDimitry Andric
12810b57cec5SDimitry Andric    template <class> friend class promise;
12820b57cec5SDimitry Andric    template <class> friend class shared_future;
12830b57cec5SDimitry Andric
12840b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
12850b57cec5SDimitry Andric    template <class _R1, class _Fp>
12860b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
12870b57cec5SDimitry Andric    template <class _R1, class _Fp>
12880b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
12890b57cec5SDimitry Andric#else
12900b57cec5SDimitry Andric    template <class _R1, class _Fp>
12910b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
12920b57cec5SDimitry Andric    template <class _R1, class _Fp>
12930b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp __f);
12940b57cec5SDimitry Andric#endif
12950b57cec5SDimitry Andric
12960b57cec5SDimitry Andricpublic:
12970b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12980b57cec5SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
12990b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
13000b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13010b57cec5SDimitry Andric    future(future&& __rhs) _NOEXCEPT
13020b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
13030b57cec5SDimitry Andric    future(const future&) = delete;
13040b57cec5SDimitry Andric    future& operator=(const future&) = delete;
13050b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13060b57cec5SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
13070b57cec5SDimitry Andric        {
13080b57cec5SDimitry Andric            future(std::move(__rhs)).swap(*this);
13090b57cec5SDimitry Andric            return *this;
13100b57cec5SDimitry Andric        }
13110b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13120b57cec5SDimitry Andricprivate:
13130b57cec5SDimitry Andric    future(const future&);
13140b57cec5SDimitry Andric    future& operator=(const future&);
13150b57cec5SDimitry Andricpublic:
13160b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13170b57cec5SDimitry Andric    ~future();
13180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13190b57cec5SDimitry Andric    shared_future<void> share() _NOEXCEPT;
13200b57cec5SDimitry Andric
13210b57cec5SDimitry Andric    // retrieving the value
13220b57cec5SDimitry Andric    void get();
13230b57cec5SDimitry Andric
13240b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13250b57cec5SDimitry Andric    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
13260b57cec5SDimitry Andric
13270b57cec5SDimitry Andric    // functions to check state
13280b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13290b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
13300b57cec5SDimitry Andric
13310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13320b57cec5SDimitry Andric    void wait() const {__state_->wait();}
13330b57cec5SDimitry Andric    template <class _Rep, class _Period>
13340b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
13350b57cec5SDimitry Andric        future_status
13360b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
13370b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
13380b57cec5SDimitry Andric    template <class _Clock, class _Duration>
13390b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
13400b57cec5SDimitry Andric        future_status
13410b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
13420b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
13430b57cec5SDimitry Andric};
13440b57cec5SDimitry Andric
13450b57cec5SDimitry Andrictemplate <class _Rp>
13460b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
13470b57cec5SDimitry Andricvoid
13480b57cec5SDimitry Andricswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
13490b57cec5SDimitry Andric{
13500b57cec5SDimitry Andric    __x.swap(__y);
13510b57cec5SDimitry Andric}
13520b57cec5SDimitry Andric
13530b57cec5SDimitry Andric// promise<R>
13540b57cec5SDimitry Andric
13550b57cec5SDimitry Andrictemplate <class _Callable> class packaged_task;
13560b57cec5SDimitry Andric
13570b57cec5SDimitry Andrictemplate <class _Rp>
13580b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
13590b57cec5SDimitry Andric{
13600b57cec5SDimitry Andric    __assoc_state<_Rp>* __state_;
13610b57cec5SDimitry Andric
13620b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13630b57cec5SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
13640b57cec5SDimitry Andric
13650b57cec5SDimitry Andric    template <class> friend class packaged_task;
13660b57cec5SDimitry Andricpublic:
13670b57cec5SDimitry Andric    promise();
13680b57cec5SDimitry Andric    template <class _Alloc>
13690b57cec5SDimitry Andric        promise(allocator_arg_t, const _Alloc& __a);
13700b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
13710b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13720b57cec5SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
13730b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
13740b57cec5SDimitry Andric    promise(const promise& __rhs) = delete;
13750b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13760b57cec5SDimitry Andricprivate:
13770b57cec5SDimitry Andric    promise(const promise& __rhs);
13780b57cec5SDimitry Andricpublic:
13790b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13800b57cec5SDimitry Andric    ~promise();
13810b57cec5SDimitry Andric
13820b57cec5SDimitry Andric    // assignment
13830b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
13840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13850b57cec5SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
13860b57cec5SDimitry Andric        {
13870b57cec5SDimitry Andric            promise(std::move(__rhs)).swap(*this);
13880b57cec5SDimitry Andric            return *this;
13890b57cec5SDimitry Andric        }
13900b57cec5SDimitry Andric    promise& operator=(const promise& __rhs) = delete;
13910b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13920b57cec5SDimitry Andricprivate:
13930b57cec5SDimitry Andric    promise& operator=(const promise& __rhs);
13940b57cec5SDimitry Andricpublic:
13950b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13960b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13970b57cec5SDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
13980b57cec5SDimitry Andric
13990b57cec5SDimitry Andric    // retrieving the result
14000b57cec5SDimitry Andric    future<_Rp> get_future();
14010b57cec5SDimitry Andric
14020b57cec5SDimitry Andric    // setting the result
14030b57cec5SDimitry Andric    void set_value(const _Rp& __r);
14040b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
14050b57cec5SDimitry Andric    void set_value(_Rp&& __r);
14060b57cec5SDimitry Andric#endif
14070b57cec5SDimitry Andric    void set_exception(exception_ptr __p);
14080b57cec5SDimitry Andric
14090b57cec5SDimitry Andric    // setting the result with deferred notification
14100b57cec5SDimitry Andric    void set_value_at_thread_exit(const _Rp& __r);
14110b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
14120b57cec5SDimitry Andric    void set_value_at_thread_exit(_Rp&& __r);
14130b57cec5SDimitry Andric#endif
14140b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr __p);
14150b57cec5SDimitry Andric};
14160b57cec5SDimitry Andric
14170b57cec5SDimitry Andrictemplate <class _Rp>
14180b57cec5SDimitry Andricpromise<_Rp>::promise()
14190b57cec5SDimitry Andric    : __state_(new __assoc_state<_Rp>)
14200b57cec5SDimitry Andric{
14210b57cec5SDimitry Andric}
14220b57cec5SDimitry Andric
14230b57cec5SDimitry Andrictemplate <class _Rp>
14240b57cec5SDimitry Andrictemplate <class _Alloc>
14250b57cec5SDimitry Andricpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
14260b57cec5SDimitry Andric{
14270b57cec5SDimitry Andric    typedef __assoc_state_alloc<_Rp, _Alloc> _State;
14280b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
14290b57cec5SDimitry Andric    typedef __allocator_destructor<_A2> _D2;
14300b57cec5SDimitry Andric    _A2 __a(__a0);
14310b57cec5SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
14320b57cec5SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
14330b57cec5SDimitry Andric    __state_ = _VSTD::addressof(*__hold.release());
14340b57cec5SDimitry Andric}
14350b57cec5SDimitry Andric
14360b57cec5SDimitry Andrictemplate <class _Rp>
14370b57cec5SDimitry Andricpromise<_Rp>::~promise()
14380b57cec5SDimitry Andric{
14390b57cec5SDimitry Andric    if (__state_)
14400b57cec5SDimitry Andric    {
14410b57cec5SDimitry Andric        if (!__state_->__has_value() && __state_->use_count() > 1)
14420b57cec5SDimitry Andric            __state_->set_exception(make_exception_ptr(
14430b57cec5SDimitry Andric                      future_error(make_error_code(future_errc::broken_promise))
14440b57cec5SDimitry Andric                                                      ));
14450b57cec5SDimitry Andric        __state_->__release_shared();
14460b57cec5SDimitry Andric    }
14470b57cec5SDimitry Andric}
14480b57cec5SDimitry Andric
14490b57cec5SDimitry Andrictemplate <class _Rp>
14500b57cec5SDimitry Andricfuture<_Rp>
14510b57cec5SDimitry Andricpromise<_Rp>::get_future()
14520b57cec5SDimitry Andric{
14530b57cec5SDimitry Andric    if (__state_ == nullptr)
14540b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
14550b57cec5SDimitry Andric    return future<_Rp>(__state_);
14560b57cec5SDimitry Andric}
14570b57cec5SDimitry Andric
14580b57cec5SDimitry Andrictemplate <class _Rp>
14590b57cec5SDimitry Andricvoid
14600b57cec5SDimitry Andricpromise<_Rp>::set_value(const _Rp& __r)
14610b57cec5SDimitry Andric{
14620b57cec5SDimitry Andric    if (__state_ == nullptr)
14630b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
14640b57cec5SDimitry Andric    __state_->set_value(__r);
14650b57cec5SDimitry Andric}
14660b57cec5SDimitry Andric
14670b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
14680b57cec5SDimitry Andric
14690b57cec5SDimitry Andrictemplate <class _Rp>
14700b57cec5SDimitry Andricvoid
14710b57cec5SDimitry Andricpromise<_Rp>::set_value(_Rp&& __r)
14720b57cec5SDimitry Andric{
14730b57cec5SDimitry Andric    if (__state_ == nullptr)
14740b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
14750b57cec5SDimitry Andric    __state_->set_value(_VSTD::move(__r));
14760b57cec5SDimitry Andric}
14770b57cec5SDimitry Andric
14780b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
14790b57cec5SDimitry Andric
14800b57cec5SDimitry Andrictemplate <class _Rp>
14810b57cec5SDimitry Andricvoid
14820b57cec5SDimitry Andricpromise<_Rp>::set_exception(exception_ptr __p)
14830b57cec5SDimitry Andric{
14840b57cec5SDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
14850b57cec5SDimitry Andric    if (__state_ == nullptr)
14860b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
14870b57cec5SDimitry Andric    __state_->set_exception(__p);
14880b57cec5SDimitry Andric}
14890b57cec5SDimitry Andric
14900b57cec5SDimitry Andrictemplate <class _Rp>
14910b57cec5SDimitry Andricvoid
14920b57cec5SDimitry Andricpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
14930b57cec5SDimitry Andric{
14940b57cec5SDimitry Andric    if (__state_ == nullptr)
14950b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
14960b57cec5SDimitry Andric    __state_->set_value_at_thread_exit(__r);
14970b57cec5SDimitry Andric}
14980b57cec5SDimitry Andric
14990b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
15000b57cec5SDimitry Andric
15010b57cec5SDimitry Andrictemplate <class _Rp>
15020b57cec5SDimitry Andricvoid
15030b57cec5SDimitry Andricpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
15040b57cec5SDimitry Andric{
15050b57cec5SDimitry Andric    if (__state_ == nullptr)
15060b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
15070b57cec5SDimitry Andric    __state_->set_value_at_thread_exit(_VSTD::move(__r));
15080b57cec5SDimitry Andric}
15090b57cec5SDimitry Andric
15100b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
15110b57cec5SDimitry Andric
15120b57cec5SDimitry Andrictemplate <class _Rp>
15130b57cec5SDimitry Andricvoid
15140b57cec5SDimitry Andricpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
15150b57cec5SDimitry Andric{
15160b57cec5SDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
15170b57cec5SDimitry Andric    if (__state_ == nullptr)
15180b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
15190b57cec5SDimitry Andric    __state_->set_exception_at_thread_exit(__p);
15200b57cec5SDimitry Andric}
15210b57cec5SDimitry Andric
15220b57cec5SDimitry Andric// promise<R&>
15230b57cec5SDimitry Andric
15240b57cec5SDimitry Andrictemplate <class _Rp>
15250b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
15260b57cec5SDimitry Andric{
15270b57cec5SDimitry Andric    __assoc_state<_Rp&>* __state_;
15280b57cec5SDimitry Andric
15290b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15300b57cec5SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
15310b57cec5SDimitry Andric
15320b57cec5SDimitry Andric    template <class> friend class packaged_task;
15330b57cec5SDimitry Andric
15340b57cec5SDimitry Andricpublic:
15350b57cec5SDimitry Andric    promise();
15360b57cec5SDimitry Andric    template <class _Allocator>
15370b57cec5SDimitry Andric        promise(allocator_arg_t, const _Allocator& __a);
15380b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
15390b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15400b57cec5SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
15410b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
15420b57cec5SDimitry Andric    promise(const promise& __rhs) = delete;
15430b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
15440b57cec5SDimitry Andricprivate:
15450b57cec5SDimitry Andric    promise(const promise& __rhs);
15460b57cec5SDimitry Andricpublic:
15470b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
15480b57cec5SDimitry Andric    ~promise();
15490b57cec5SDimitry Andric
15500b57cec5SDimitry Andric    // assignment
15510b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
15520b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15530b57cec5SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
15540b57cec5SDimitry Andric        {
15550b57cec5SDimitry Andric            promise(std::move(__rhs)).swap(*this);
15560b57cec5SDimitry Andric            return *this;
15570b57cec5SDimitry Andric        }
15580b57cec5SDimitry Andric    promise& operator=(const promise& __rhs) = delete;
15590b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
15600b57cec5SDimitry Andricprivate:
15610b57cec5SDimitry Andric    promise& operator=(const promise& __rhs);
15620b57cec5SDimitry Andricpublic:
15630b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
15640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15650b57cec5SDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
15660b57cec5SDimitry Andric
15670b57cec5SDimitry Andric    // retrieving the result
15680b57cec5SDimitry Andric    future<_Rp&> get_future();
15690b57cec5SDimitry Andric
15700b57cec5SDimitry Andric    // setting the result
15710b57cec5SDimitry Andric    void set_value(_Rp& __r);
15720b57cec5SDimitry Andric    void set_exception(exception_ptr __p);
15730b57cec5SDimitry Andric
15740b57cec5SDimitry Andric    // setting the result with deferred notification
15750b57cec5SDimitry Andric    void set_value_at_thread_exit(_Rp&);
15760b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr __p);
15770b57cec5SDimitry Andric};
15780b57cec5SDimitry Andric
15790b57cec5SDimitry Andrictemplate <class _Rp>
15800b57cec5SDimitry Andricpromise<_Rp&>::promise()
15810b57cec5SDimitry Andric    : __state_(new __assoc_state<_Rp&>)
15820b57cec5SDimitry Andric{
15830b57cec5SDimitry Andric}
15840b57cec5SDimitry Andric
15850b57cec5SDimitry Andrictemplate <class _Rp>
15860b57cec5SDimitry Andrictemplate <class _Alloc>
15870b57cec5SDimitry Andricpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
15880b57cec5SDimitry Andric{
15890b57cec5SDimitry Andric    typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
15900b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
15910b57cec5SDimitry Andric    typedef __allocator_destructor<_A2> _D2;
15920b57cec5SDimitry Andric    _A2 __a(__a0);
15930b57cec5SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
15940b57cec5SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
15950b57cec5SDimitry Andric    __state_ = _VSTD::addressof(*__hold.release());
15960b57cec5SDimitry Andric}
15970b57cec5SDimitry Andric
15980b57cec5SDimitry Andrictemplate <class _Rp>
15990b57cec5SDimitry Andricpromise<_Rp&>::~promise()
16000b57cec5SDimitry Andric{
16010b57cec5SDimitry Andric    if (__state_)
16020b57cec5SDimitry Andric    {
16030b57cec5SDimitry Andric        if (!__state_->__has_value() && __state_->use_count() > 1)
16040b57cec5SDimitry Andric            __state_->set_exception(make_exception_ptr(
16050b57cec5SDimitry Andric                      future_error(make_error_code(future_errc::broken_promise))
16060b57cec5SDimitry Andric                                                      ));
16070b57cec5SDimitry Andric        __state_->__release_shared();
16080b57cec5SDimitry Andric    }
16090b57cec5SDimitry Andric}
16100b57cec5SDimitry Andric
16110b57cec5SDimitry Andrictemplate <class _Rp>
16120b57cec5SDimitry Andricfuture<_Rp&>
16130b57cec5SDimitry Andricpromise<_Rp&>::get_future()
16140b57cec5SDimitry Andric{
16150b57cec5SDimitry Andric    if (__state_ == nullptr)
16160b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
16170b57cec5SDimitry Andric    return future<_Rp&>(__state_);
16180b57cec5SDimitry Andric}
16190b57cec5SDimitry Andric
16200b57cec5SDimitry Andrictemplate <class _Rp>
16210b57cec5SDimitry Andricvoid
16220b57cec5SDimitry Andricpromise<_Rp&>::set_value(_Rp& __r)
16230b57cec5SDimitry Andric{
16240b57cec5SDimitry Andric    if (__state_ == nullptr)
16250b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
16260b57cec5SDimitry Andric    __state_->set_value(__r);
16270b57cec5SDimitry Andric}
16280b57cec5SDimitry Andric
16290b57cec5SDimitry Andrictemplate <class _Rp>
16300b57cec5SDimitry Andricvoid
16310b57cec5SDimitry Andricpromise<_Rp&>::set_exception(exception_ptr __p)
16320b57cec5SDimitry Andric{
16330b57cec5SDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
16340b57cec5SDimitry Andric    if (__state_ == nullptr)
16350b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
16360b57cec5SDimitry Andric    __state_->set_exception(__p);
16370b57cec5SDimitry Andric}
16380b57cec5SDimitry Andric
16390b57cec5SDimitry Andrictemplate <class _Rp>
16400b57cec5SDimitry Andricvoid
16410b57cec5SDimitry Andricpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
16420b57cec5SDimitry Andric{
16430b57cec5SDimitry Andric    if (__state_ == nullptr)
16440b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
16450b57cec5SDimitry Andric    __state_->set_value_at_thread_exit(__r);
16460b57cec5SDimitry Andric}
16470b57cec5SDimitry Andric
16480b57cec5SDimitry Andrictemplate <class _Rp>
16490b57cec5SDimitry Andricvoid
16500b57cec5SDimitry Andricpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
16510b57cec5SDimitry Andric{
16520b57cec5SDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
16530b57cec5SDimitry Andric    if (__state_ == nullptr)
16540b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
16550b57cec5SDimitry Andric    __state_->set_exception_at_thread_exit(__p);
16560b57cec5SDimitry Andric}
16570b57cec5SDimitry Andric
16580b57cec5SDimitry Andric// promise<void>
16590b57cec5SDimitry Andric
16600b57cec5SDimitry Andrictemplate <>
16610b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
16620b57cec5SDimitry Andric{
16630b57cec5SDimitry Andric    __assoc_sub_state* __state_;
16640b57cec5SDimitry Andric
16650b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16660b57cec5SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
16670b57cec5SDimitry Andric
16680b57cec5SDimitry Andric    template <class> friend class packaged_task;
16690b57cec5SDimitry Andric
16700b57cec5SDimitry Andricpublic:
16710b57cec5SDimitry Andric    promise();
16720b57cec5SDimitry Andric    template <class _Allocator>
16730b57cec5SDimitry Andric        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
16740b57cec5SDimitry Andric        promise(allocator_arg_t, const _Allocator& __a);
16750b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
16760b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16770b57cec5SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
16780b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
16790b57cec5SDimitry Andric    promise(const promise& __rhs) = delete;
16800b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
16810b57cec5SDimitry Andricprivate:
16820b57cec5SDimitry Andric    promise(const promise& __rhs);
16830b57cec5SDimitry Andricpublic:
16840b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
16850b57cec5SDimitry Andric    ~promise();
16860b57cec5SDimitry Andric
16870b57cec5SDimitry Andric    // assignment
16880b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
16890b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16900b57cec5SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
16910b57cec5SDimitry Andric        {
16920b57cec5SDimitry Andric            promise(std::move(__rhs)).swap(*this);
16930b57cec5SDimitry Andric            return *this;
16940b57cec5SDimitry Andric        }
16950b57cec5SDimitry Andric    promise& operator=(const promise& __rhs) = delete;
16960b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
16970b57cec5SDimitry Andricprivate:
16980b57cec5SDimitry Andric    promise& operator=(const promise& __rhs);
16990b57cec5SDimitry Andricpublic:
17000b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
17010b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17020b57cec5SDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
17030b57cec5SDimitry Andric
17040b57cec5SDimitry Andric    // retrieving the result
17050b57cec5SDimitry Andric    future<void> get_future();
17060b57cec5SDimitry Andric
17070b57cec5SDimitry Andric    // setting the result
17080b57cec5SDimitry Andric    void set_value();
17090b57cec5SDimitry Andric    void set_exception(exception_ptr __p);
17100b57cec5SDimitry Andric
17110b57cec5SDimitry Andric    // setting the result with deferred notification
17120b57cec5SDimitry Andric    void set_value_at_thread_exit();
17130b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr __p);
17140b57cec5SDimitry Andric};
17150b57cec5SDimitry Andric
17160b57cec5SDimitry Andrictemplate <class _Alloc>
17170b57cec5SDimitry Andricpromise<void>::promise(allocator_arg_t, const _Alloc& __a0)
17180b57cec5SDimitry Andric{
17190b57cec5SDimitry Andric    typedef __assoc_sub_state_alloc<_Alloc> _State;
17200b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
17210b57cec5SDimitry Andric    typedef __allocator_destructor<_A2> _D2;
17220b57cec5SDimitry Andric    _A2 __a(__a0);
17230b57cec5SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
17240b57cec5SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
17250b57cec5SDimitry Andric    __state_ = _VSTD::addressof(*__hold.release());
17260b57cec5SDimitry Andric}
17270b57cec5SDimitry Andric
17280b57cec5SDimitry Andrictemplate <class _Rp>
17290b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
17300b57cec5SDimitry Andricvoid
17310b57cec5SDimitry Andricswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
17320b57cec5SDimitry Andric{
17330b57cec5SDimitry Andric    __x.swap(__y);
17340b57cec5SDimitry Andric}
17350b57cec5SDimitry Andric
17360b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
17370b57cec5SDimitry Andric    struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
17380b57cec5SDimitry Andric        : public true_type {};
17390b57cec5SDimitry Andric
17400b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS
17410b57cec5SDimitry Andric
17420b57cec5SDimitry Andric// packaged_task
17430b57cec5SDimitry Andric
17440b57cec5SDimitry Andrictemplate<class _Fp> class __packaged_task_base;
17450b57cec5SDimitry Andric
17460b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
17470b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
17480b57cec5SDimitry Andric{
17490b57cec5SDimitry Andric    __packaged_task_base(const __packaged_task_base&);
17500b57cec5SDimitry Andric    __packaged_task_base& operator=(const __packaged_task_base&);
17510b57cec5SDimitry Andricpublic:
17520b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17530b57cec5SDimitry Andric    __packaged_task_base() {}
17540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17550b57cec5SDimitry Andric    virtual ~__packaged_task_base() {}
17560b57cec5SDimitry Andric    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
17570b57cec5SDimitry Andric    virtual void destroy() = 0;
17580b57cec5SDimitry Andric    virtual void destroy_deallocate() = 0;
17590b57cec5SDimitry Andric    virtual _Rp operator()(_ArgTypes&& ...) = 0;
17600b57cec5SDimitry Andric};
17610b57cec5SDimitry Andric
17620b57cec5SDimitry Andrictemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func;
17630b57cec5SDimitry Andric
17640b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
17650b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
17660b57cec5SDimitry Andric    : public  __packaged_task_base<_Rp(_ArgTypes...)>
17670b57cec5SDimitry Andric{
17680b57cec5SDimitry Andric    __compressed_pair<_Fp, _Alloc> __f_;
17690b57cec5SDimitry Andricpublic:
17700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1771480093f4SDimitry Andric    explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
17720b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1773480093f4SDimitry Andric    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
17740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17750b57cec5SDimitry Andric    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
17760b57cec5SDimitry Andric        : __f_(__f, __a) {}
17770b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17780b57cec5SDimitry Andric    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
17790b57cec5SDimitry Andric        : __f_(_VSTD::move(__f), __a) {}
17800b57cec5SDimitry Andric    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
17810b57cec5SDimitry Andric    virtual void destroy();
17820b57cec5SDimitry Andric    virtual void destroy_deallocate();
17830b57cec5SDimitry Andric    virtual _Rp operator()(_ArgTypes&& ... __args);
17840b57cec5SDimitry Andric};
17850b57cec5SDimitry Andric
17860b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
17870b57cec5SDimitry Andricvoid
17880b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
17890b57cec5SDimitry Andric                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
17900b57cec5SDimitry Andric{
17910b57cec5SDimitry Andric    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
17920b57cec5SDimitry Andric}
17930b57cec5SDimitry Andric
17940b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
17950b57cec5SDimitry Andricvoid
17960b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
17970b57cec5SDimitry Andric{
17980b57cec5SDimitry Andric    __f_.~__compressed_pair<_Fp, _Alloc>();
17990b57cec5SDimitry Andric}
18000b57cec5SDimitry Andric
18010b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
18020b57cec5SDimitry Andricvoid
18030b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
18040b57cec5SDimitry Andric{
18050b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
18060b57cec5SDimitry Andric    typedef allocator_traits<_Ap> _ATraits;
18070b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
18080b57cec5SDimitry Andric    _Ap __a(__f_.second());
18090b57cec5SDimitry Andric    __f_.~__compressed_pair<_Fp, _Alloc>();
18100b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
18110b57cec5SDimitry Andric}
18120b57cec5SDimitry Andric
18130b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
18140b57cec5SDimitry Andric_Rp
18150b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
18160b57cec5SDimitry Andric{
18170b57cec5SDimitry Andric    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
18180b57cec5SDimitry Andric}
18190b57cec5SDimitry Andric
18200b57cec5SDimitry Andrictemplate <class _Callable> class __packaged_task_function;
18210b57cec5SDimitry Andric
18220b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
18230b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
18240b57cec5SDimitry Andric{
18250b57cec5SDimitry Andric    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
18260b57cec5SDimitry Andric    typename aligned_storage<3*sizeof(void*)>::type __buf_;
18270b57cec5SDimitry Andric    __base* __f_;
18280b57cec5SDimitry Andric
18290b57cec5SDimitry Andricpublic:
18300b57cec5SDimitry Andric    typedef _Rp result_type;
18310b57cec5SDimitry Andric
18320b57cec5SDimitry Andric    // construct/copy/destroy:
18330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18340b57cec5SDimitry Andric    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
18350b57cec5SDimitry Andric    template<class _Fp>
18360b57cec5SDimitry Andric      __packaged_task_function(_Fp&& __f);
18370b57cec5SDimitry Andric    template<class _Fp, class _Alloc>
18380b57cec5SDimitry Andric      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
18390b57cec5SDimitry Andric
18400b57cec5SDimitry Andric    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
18410b57cec5SDimitry Andric    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
18420b57cec5SDimitry Andric
18430b57cec5SDimitry Andric    __packaged_task_function(const __packaged_task_function&) =  delete;
18440b57cec5SDimitry Andric    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
18450b57cec5SDimitry Andric
18460b57cec5SDimitry Andric    ~__packaged_task_function();
18470b57cec5SDimitry Andric
18480b57cec5SDimitry Andric    void swap(__packaged_task_function&) _NOEXCEPT;
18490b57cec5SDimitry Andric
18500b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18510b57cec5SDimitry Andric    _Rp operator()(_ArgTypes...) const;
18520b57cec5SDimitry Andric};
18530b57cec5SDimitry Andric
18540b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
18550b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
18560b57cec5SDimitry Andric{
18570b57cec5SDimitry Andric    if (__f.__f_ == nullptr)
18580b57cec5SDimitry Andric        __f_ = nullptr;
18590b57cec5SDimitry Andric    else if (__f.__f_ == (__base*)&__f.__buf_)
18600b57cec5SDimitry Andric    {
18610b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
18620b57cec5SDimitry Andric        __f.__f_->__move_to(__f_);
18630b57cec5SDimitry Andric    }
18640b57cec5SDimitry Andric    else
18650b57cec5SDimitry Andric    {
18660b57cec5SDimitry Andric        __f_ = __f.__f_;
18670b57cec5SDimitry Andric        __f.__f_ = nullptr;
18680b57cec5SDimitry Andric    }
18690b57cec5SDimitry Andric}
18700b57cec5SDimitry Andric
18710b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
18720b57cec5SDimitry Andrictemplate <class _Fp>
18730b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
18740b57cec5SDimitry Andric    : __f_(nullptr)
18750b57cec5SDimitry Andric{
18760b57cec5SDimitry Andric    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
18770b57cec5SDimitry Andric    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
18780b57cec5SDimitry Andric    if (sizeof(_FF) <= sizeof(__buf_))
18790b57cec5SDimitry Andric    {
18800b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
18810b57cec5SDimitry Andric        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
18820b57cec5SDimitry Andric    }
18830b57cec5SDimitry Andric    else
18840b57cec5SDimitry Andric    {
18850b57cec5SDimitry Andric        typedef allocator<_FF> _Ap;
18860b57cec5SDimitry Andric        _Ap __a;
18870b57cec5SDimitry Andric        typedef __allocator_destructor<_Ap> _Dp;
18880b57cec5SDimitry Andric        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
18890b57cec5SDimitry Andric        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
18900b57cec5SDimitry Andric        __f_ = __hold.release();
18910b57cec5SDimitry Andric    }
18920b57cec5SDimitry Andric}
18930b57cec5SDimitry Andric
18940b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
18950b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc>
18960b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
18970b57cec5SDimitry Andric                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
18980b57cec5SDimitry Andric    : __f_(nullptr)
18990b57cec5SDimitry Andric{
19000b57cec5SDimitry Andric    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
19010b57cec5SDimitry Andric    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
19020b57cec5SDimitry Andric    if (sizeof(_FF) <= sizeof(__buf_))
19030b57cec5SDimitry Andric    {
19040b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
19050b57cec5SDimitry Andric        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
19060b57cec5SDimitry Andric    }
19070b57cec5SDimitry Andric    else
19080b57cec5SDimitry Andric    {
19090b57cec5SDimitry Andric        typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
19100b57cec5SDimitry Andric        _Ap __a(__a0);
19110b57cec5SDimitry Andric        typedef __allocator_destructor<_Ap> _Dp;
19120b57cec5SDimitry Andric        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
19130b57cec5SDimitry Andric        ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
19140b57cec5SDimitry Andric            _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
19150b57cec5SDimitry Andric        __f_ = _VSTD::addressof(*__hold.release());
19160b57cec5SDimitry Andric    }
19170b57cec5SDimitry Andric}
19180b57cec5SDimitry Andric
19190b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
19200b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>&
19210b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
19220b57cec5SDimitry Andric{
19230b57cec5SDimitry Andric    if (__f_ == (__base*)&__buf_)
19240b57cec5SDimitry Andric        __f_->destroy();
19250b57cec5SDimitry Andric    else if (__f_)
19260b57cec5SDimitry Andric        __f_->destroy_deallocate();
19270b57cec5SDimitry Andric    __f_ = nullptr;
19280b57cec5SDimitry Andric    if (__f.__f_ == nullptr)
19290b57cec5SDimitry Andric        __f_ = nullptr;
19300b57cec5SDimitry Andric    else if (__f.__f_ == (__base*)&__f.__buf_)
19310b57cec5SDimitry Andric    {
19320b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
19330b57cec5SDimitry Andric        __f.__f_->__move_to(__f_);
19340b57cec5SDimitry Andric    }
19350b57cec5SDimitry Andric    else
19360b57cec5SDimitry Andric    {
19370b57cec5SDimitry Andric        __f_ = __f.__f_;
19380b57cec5SDimitry Andric        __f.__f_ = nullptr;
19390b57cec5SDimitry Andric    }
19400b57cec5SDimitry Andric    return *this;
19410b57cec5SDimitry Andric}
19420b57cec5SDimitry Andric
19430b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
19440b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
19450b57cec5SDimitry Andric{
19460b57cec5SDimitry Andric    if (__f_ == (__base*)&__buf_)
19470b57cec5SDimitry Andric        __f_->destroy();
19480b57cec5SDimitry Andric    else if (__f_)
19490b57cec5SDimitry Andric        __f_->destroy_deallocate();
19500b57cec5SDimitry Andric}
19510b57cec5SDimitry Andric
19520b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
19530b57cec5SDimitry Andricvoid
19540b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
19550b57cec5SDimitry Andric{
19560b57cec5SDimitry Andric    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
19570b57cec5SDimitry Andric    {
19580b57cec5SDimitry Andric        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
19590b57cec5SDimitry Andric        __base* __t = (__base*)&__tempbuf;
19600b57cec5SDimitry Andric        __f_->__move_to(__t);
19610b57cec5SDimitry Andric        __f_->destroy();
19620b57cec5SDimitry Andric        __f_ = nullptr;
19630b57cec5SDimitry Andric        __f.__f_->__move_to((__base*)&__buf_);
19640b57cec5SDimitry Andric        __f.__f_->destroy();
19650b57cec5SDimitry Andric        __f.__f_ = nullptr;
19660b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
19670b57cec5SDimitry Andric        __t->__move_to((__base*)&__f.__buf_);
19680b57cec5SDimitry Andric        __t->destroy();
19690b57cec5SDimitry Andric        __f.__f_ = (__base*)&__f.__buf_;
19700b57cec5SDimitry Andric    }
19710b57cec5SDimitry Andric    else if (__f_ == (__base*)&__buf_)
19720b57cec5SDimitry Andric    {
19730b57cec5SDimitry Andric        __f_->__move_to((__base*)&__f.__buf_);
19740b57cec5SDimitry Andric        __f_->destroy();
19750b57cec5SDimitry Andric        __f_ = __f.__f_;
19760b57cec5SDimitry Andric        __f.__f_ = (__base*)&__f.__buf_;
19770b57cec5SDimitry Andric    }
19780b57cec5SDimitry Andric    else if (__f.__f_ == (__base*)&__f.__buf_)
19790b57cec5SDimitry Andric    {
19800b57cec5SDimitry Andric        __f.__f_->__move_to((__base*)&__buf_);
19810b57cec5SDimitry Andric        __f.__f_->destroy();
19820b57cec5SDimitry Andric        __f.__f_ = __f_;
19830b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
19840b57cec5SDimitry Andric    }
19850b57cec5SDimitry Andric    else
19860b57cec5SDimitry Andric        _VSTD::swap(__f_, __f.__f_);
19870b57cec5SDimitry Andric}
19880b57cec5SDimitry Andric
19890b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
19900b57cec5SDimitry Andricinline
19910b57cec5SDimitry Andric_Rp
19920b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
19930b57cec5SDimitry Andric{
19940b57cec5SDimitry Andric    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
19950b57cec5SDimitry Andric}
19960b57cec5SDimitry Andric
19970b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
19980b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
19990b57cec5SDimitry Andric{
20000b57cec5SDimitry Andricpublic:
20010b57cec5SDimitry Andric    typedef _Rp result_type; // extension
20020b57cec5SDimitry Andric
20030b57cec5SDimitry Andricprivate:
20040b57cec5SDimitry Andric    __packaged_task_function<result_type(_ArgTypes...)> __f_;
20050b57cec5SDimitry Andric    promise<result_type>                                __p_;
20060b57cec5SDimitry Andric
20070b57cec5SDimitry Andricpublic:
20080b57cec5SDimitry Andric    // construction and destruction
20090b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
20100b57cec5SDimitry Andric    packaged_task() _NOEXCEPT : __p_(nullptr) {}
20110b57cec5SDimitry Andric    template <class _Fp,
20120b57cec5SDimitry Andric              class = typename enable_if
20130b57cec5SDimitry Andric              <
20140b57cec5SDimitry Andric                  !is_same<
20150b57cec5SDimitry Andric                      typename __uncvref<_Fp>::type,
20160b57cec5SDimitry Andric                      packaged_task
20170b57cec5SDimitry Andric                      >::value
20180b57cec5SDimitry Andric                  >::type
20190b57cec5SDimitry Andric             >
20200b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
20210b57cec5SDimitry Andric        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
20220b57cec5SDimitry Andric    template <class _Fp, class _Allocator,
20230b57cec5SDimitry Andric              class = typename enable_if
20240b57cec5SDimitry Andric              <
20250b57cec5SDimitry Andric                  !is_same<
20260b57cec5SDimitry Andric                      typename __uncvref<_Fp>::type,
20270b57cec5SDimitry Andric                      packaged_task
20280b57cec5SDimitry Andric                      >::value
20290b57cec5SDimitry Andric                  >::type
20300b57cec5SDimitry Andric              >
20310b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
20320b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
20330b57cec5SDimitry Andric             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
20340b57cec5SDimitry Andric               __p_(allocator_arg, __a) {}
20350b57cec5SDimitry Andric    // ~packaged_task() = default;
20360b57cec5SDimitry Andric
20370b57cec5SDimitry Andric    // no copy
20380b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
20390b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
20400b57cec5SDimitry Andric
20410b57cec5SDimitry Andric    // move support
20420b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
20430b57cec5SDimitry Andric    packaged_task(packaged_task&& __other) _NOEXCEPT
20440b57cec5SDimitry Andric        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
20450b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
20460b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
20470b57cec5SDimitry Andric    {
20480b57cec5SDimitry Andric        __f_ = _VSTD::move(__other.__f_);
20490b57cec5SDimitry Andric        __p_ = _VSTD::move(__other.__p_);
20500b57cec5SDimitry Andric        return *this;
20510b57cec5SDimitry Andric    }
20520b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
20530b57cec5SDimitry Andric    void swap(packaged_task& __other) _NOEXCEPT
20540b57cec5SDimitry Andric    {
20550b57cec5SDimitry Andric        __f_.swap(__other.__f_);
20560b57cec5SDimitry Andric        __p_.swap(__other.__p_);
20570b57cec5SDimitry Andric    }
20580b57cec5SDimitry Andric
20590b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
20600b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
20610b57cec5SDimitry Andric
20620b57cec5SDimitry Andric    // result retrieval
20630b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
20640b57cec5SDimitry Andric    future<result_type> get_future() {return __p_.get_future();}
20650b57cec5SDimitry Andric
20660b57cec5SDimitry Andric    // execution
20670b57cec5SDimitry Andric    void operator()(_ArgTypes... __args);
20680b57cec5SDimitry Andric    void make_ready_at_thread_exit(_ArgTypes... __args);
20690b57cec5SDimitry Andric
20700b57cec5SDimitry Andric    void reset();
20710b57cec5SDimitry Andric};
20720b57cec5SDimitry Andric
20730b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
20740b57cec5SDimitry Andricvoid
20750b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
20760b57cec5SDimitry Andric{
20770b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
20780b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
20790b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
20800b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
20810b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
20820b57cec5SDimitry Andric    try
20830b57cec5SDimitry Andric    {
20840b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
20850b57cec5SDimitry Andric        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
20860b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
20870b57cec5SDimitry Andric    }
20880b57cec5SDimitry Andric    catch (...)
20890b57cec5SDimitry Andric    {
20900b57cec5SDimitry Andric        __p_.set_exception(current_exception());
20910b57cec5SDimitry Andric    }
20920b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
20930b57cec5SDimitry Andric}
20940b57cec5SDimitry Andric
20950b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
20960b57cec5SDimitry Andricvoid
20970b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
20980b57cec5SDimitry Andric{
20990b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
21000b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
21010b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
21020b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
21030b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
21040b57cec5SDimitry Andric    try
21050b57cec5SDimitry Andric    {
21060b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
21070b57cec5SDimitry Andric        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
21080b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
21090b57cec5SDimitry Andric    }
21100b57cec5SDimitry Andric    catch (...)
21110b57cec5SDimitry Andric    {
21120b57cec5SDimitry Andric        __p_.set_exception_at_thread_exit(current_exception());
21130b57cec5SDimitry Andric    }
21140b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
21150b57cec5SDimitry Andric}
21160b57cec5SDimitry Andric
21170b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
21180b57cec5SDimitry Andricvoid
21190b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::reset()
21200b57cec5SDimitry Andric{
21210b57cec5SDimitry Andric    if (!valid())
21220b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
21230b57cec5SDimitry Andric    __p_ = promise<result_type>();
21240b57cec5SDimitry Andric}
21250b57cec5SDimitry Andric
21260b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
21270b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
21280b57cec5SDimitry Andric{
21290b57cec5SDimitry Andricpublic:
21300b57cec5SDimitry Andric    typedef void result_type; // extension
21310b57cec5SDimitry Andric
21320b57cec5SDimitry Andricprivate:
21330b57cec5SDimitry Andric    __packaged_task_function<result_type(_ArgTypes...)> __f_;
21340b57cec5SDimitry Andric    promise<result_type>                                __p_;
21350b57cec5SDimitry Andric
21360b57cec5SDimitry Andricpublic:
21370b57cec5SDimitry Andric    // construction and destruction
21380b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21390b57cec5SDimitry Andric    packaged_task() _NOEXCEPT : __p_(nullptr) {}
21400b57cec5SDimitry Andric    template <class _Fp,
21410b57cec5SDimitry Andric              class = typename enable_if
21420b57cec5SDimitry Andric              <
21430b57cec5SDimitry Andric                  !is_same<
21440b57cec5SDimitry Andric                      typename __uncvref<_Fp>::type,
21450b57cec5SDimitry Andric                      packaged_task
21460b57cec5SDimitry Andric                      >::value
21470b57cec5SDimitry Andric                  >::type
21480b57cec5SDimitry Andric              >
21490b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
21500b57cec5SDimitry Andric        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
21510b57cec5SDimitry Andric    template <class _Fp, class _Allocator,
21520b57cec5SDimitry Andric              class = typename enable_if
21530b57cec5SDimitry Andric              <
21540b57cec5SDimitry Andric                  !is_same<
21550b57cec5SDimitry Andric                      typename __uncvref<_Fp>::type,
21560b57cec5SDimitry Andric                      packaged_task
21570b57cec5SDimitry Andric                      >::value
21580b57cec5SDimitry Andric                  >::type
21590b57cec5SDimitry Andric              >
21600b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
21610b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
21620b57cec5SDimitry Andric             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
21630b57cec5SDimitry Andric               __p_(allocator_arg, __a) {}
21640b57cec5SDimitry Andric    // ~packaged_task() = default;
21650b57cec5SDimitry Andric
21660b57cec5SDimitry Andric    // no copy
21670b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
21680b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
21690b57cec5SDimitry Andric
21700b57cec5SDimitry Andric    // move support
21710b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21720b57cec5SDimitry Andric    packaged_task(packaged_task&& __other) _NOEXCEPT
21730b57cec5SDimitry Andric        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
21740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21750b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
21760b57cec5SDimitry Andric    {
21770b57cec5SDimitry Andric        __f_ = _VSTD::move(__other.__f_);
21780b57cec5SDimitry Andric        __p_ = _VSTD::move(__other.__p_);
21790b57cec5SDimitry Andric        return *this;
21800b57cec5SDimitry Andric    }
21810b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21820b57cec5SDimitry Andric    void swap(packaged_task& __other) _NOEXCEPT
21830b57cec5SDimitry Andric    {
21840b57cec5SDimitry Andric        __f_.swap(__other.__f_);
21850b57cec5SDimitry Andric        __p_.swap(__other.__p_);
21860b57cec5SDimitry Andric    }
21870b57cec5SDimitry Andric
21880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21890b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
21900b57cec5SDimitry Andric
21910b57cec5SDimitry Andric    // result retrieval
21920b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21930b57cec5SDimitry Andric    future<result_type> get_future() {return __p_.get_future();}
21940b57cec5SDimitry Andric
21950b57cec5SDimitry Andric    // execution
21960b57cec5SDimitry Andric    void operator()(_ArgTypes... __args);
21970b57cec5SDimitry Andric    void make_ready_at_thread_exit(_ArgTypes... __args);
21980b57cec5SDimitry Andric
21990b57cec5SDimitry Andric    void reset();
22000b57cec5SDimitry Andric};
22010b57cec5SDimitry Andric
22020b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
22030b57cec5SDimitry Andricvoid
22040b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
22050b57cec5SDimitry Andric{
22060b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
22070b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
22080b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
22090b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
22100b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22110b57cec5SDimitry Andric    try
22120b57cec5SDimitry Andric    {
22130b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
22140b57cec5SDimitry Andric        __f_(_VSTD::forward<_ArgTypes>(__args)...);
22150b57cec5SDimitry Andric        __p_.set_value();
22160b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22170b57cec5SDimitry Andric    }
22180b57cec5SDimitry Andric    catch (...)
22190b57cec5SDimitry Andric    {
22200b57cec5SDimitry Andric        __p_.set_exception(current_exception());
22210b57cec5SDimitry Andric    }
22220b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
22230b57cec5SDimitry Andric}
22240b57cec5SDimitry Andric
22250b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
22260b57cec5SDimitry Andricvoid
22270b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
22280b57cec5SDimitry Andric{
22290b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
22300b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
22310b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
22320b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
22330b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22340b57cec5SDimitry Andric    try
22350b57cec5SDimitry Andric    {
22360b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
22370b57cec5SDimitry Andric        __f_(_VSTD::forward<_ArgTypes>(__args)...);
22380b57cec5SDimitry Andric        __p_.set_value_at_thread_exit();
22390b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22400b57cec5SDimitry Andric    }
22410b57cec5SDimitry Andric    catch (...)
22420b57cec5SDimitry Andric    {
22430b57cec5SDimitry Andric        __p_.set_exception_at_thread_exit(current_exception());
22440b57cec5SDimitry Andric    }
22450b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
22460b57cec5SDimitry Andric}
22470b57cec5SDimitry Andric
22480b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
22490b57cec5SDimitry Andricvoid
22500b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::reset()
22510b57cec5SDimitry Andric{
22520b57cec5SDimitry Andric    if (!valid())
22530b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
22540b57cec5SDimitry Andric    __p_ = promise<result_type>();
22550b57cec5SDimitry Andric}
22560b57cec5SDimitry Andric
22570b57cec5SDimitry Andrictemplate <class _Callable>
22580b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
22590b57cec5SDimitry Andricvoid
22600b57cec5SDimitry Andricswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
22610b57cec5SDimitry Andric{
22620b57cec5SDimitry Andric    __x.swap(__y);
22630b57cec5SDimitry Andric}
22640b57cec5SDimitry Andric
22650b57cec5SDimitry Andrictemplate <class _Callable, class _Alloc>
22660b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
22670b57cec5SDimitry Andric    : public true_type {};
22680b57cec5SDimitry Andric
22690b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
2270480093f4SDimitry Andric_LIBCPP_INLINE_VISIBILITY future<_Rp>
22710b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
22720b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp&& __f)
22730b57cec5SDimitry Andric#else
22740b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp __f)
22750b57cec5SDimitry Andric#endif
22760b57cec5SDimitry Andric{
22770b57cec5SDimitry Andric    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
22780b57cec5SDimitry Andric        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
22790b57cec5SDimitry Andric    return future<_Rp>(__h.get());
22800b57cec5SDimitry Andric}
22810b57cec5SDimitry Andric
22820b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
2283480093f4SDimitry Andric_LIBCPP_INLINE_VISIBILITY future<_Rp>
22840b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
22850b57cec5SDimitry Andric__make_async_assoc_state(_Fp&& __f)
22860b57cec5SDimitry Andric#else
22870b57cec5SDimitry Andric__make_async_assoc_state(_Fp __f)
22880b57cec5SDimitry Andric#endif
22890b57cec5SDimitry Andric{
22900b57cec5SDimitry Andric    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
22910b57cec5SDimitry Andric        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
22920b57cec5SDimitry Andric    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
22930b57cec5SDimitry Andric    return future<_Rp>(__h.get());
22940b57cec5SDimitry Andric}
22950b57cec5SDimitry Andric
22960b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
2297480093f4SDimitry Andricclass _LIBCPP_HIDDEN __async_func
22980b57cec5SDimitry Andric{
22990b57cec5SDimitry Andric    tuple<_Fp, _Args...> __f_;
23000b57cec5SDimitry Andric
23010b57cec5SDimitry Andricpublic:
23020b57cec5SDimitry Andric    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
23030b57cec5SDimitry Andric
23040b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
23050b57cec5SDimitry Andric    explicit __async_func(_Fp&& __f, _Args&&... __args)
23060b57cec5SDimitry Andric        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
23070b57cec5SDimitry Andric
23080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
23090b57cec5SDimitry Andric    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
23100b57cec5SDimitry Andric
23110b57cec5SDimitry Andric    _Rp operator()()
23120b57cec5SDimitry Andric    {
23130b57cec5SDimitry Andric        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
23140b57cec5SDimitry Andric        return __execute(_Index());
23150b57cec5SDimitry Andric    }
23160b57cec5SDimitry Andricprivate:
23170b57cec5SDimitry Andric    template <size_t ..._Indices>
23180b57cec5SDimitry Andric    _Rp
23190b57cec5SDimitry Andric    __execute(__tuple_indices<_Indices...>)
23200b57cec5SDimitry Andric    {
23210b57cec5SDimitry Andric        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
23220b57cec5SDimitry Andric    }
23230b57cec5SDimitry Andric};
23240b57cec5SDimitry Andric
23250b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
23260b57cec5SDimitry Andric{ return (int(__policy) & int(__value)) != 0; }
23270b57cec5SDimitry Andric
23280b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
23290b57cec5SDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17
23300b57cec5SDimitry Andricfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
23310b57cec5SDimitry Andricasync(launch __policy, _Fp&& __f, _Args&&... __args)
23320b57cec5SDimitry Andric{
23330b57cec5SDimitry Andric    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
23340b57cec5SDimitry Andric    typedef typename _BF::_Rp _Rp;
23350b57cec5SDimitry Andric
23360b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23370b57cec5SDimitry Andric    try
23380b57cec5SDimitry Andric    {
23390b57cec5SDimitry Andric#endif
23400b57cec5SDimitry Andric        if (__does_policy_contain(__policy, launch::async))
23410b57cec5SDimitry Andric        return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
23420b57cec5SDimitry Andric                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
23430b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23440b57cec5SDimitry Andric    }
23450b57cec5SDimitry Andric    catch ( ... ) { if (__policy == launch::async) throw ; }
23460b57cec5SDimitry Andric#endif
23470b57cec5SDimitry Andric
23480b57cec5SDimitry Andric    if (__does_policy_contain(__policy, launch::deferred))
23490b57cec5SDimitry Andric        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
23500b57cec5SDimitry Andric                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
23510b57cec5SDimitry Andric    return future<_Rp>{};
23520b57cec5SDimitry Andric}
23530b57cec5SDimitry Andric
23540b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
23550b57cec5SDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
23560b57cec5SDimitry Andricfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
23570b57cec5SDimitry Andricasync(_Fp&& __f, _Args&&... __args)
23580b57cec5SDimitry Andric{
23590b57cec5SDimitry Andric    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
23600b57cec5SDimitry Andric                                    _VSTD::forward<_Args>(__args)...);
23610b57cec5SDimitry Andric}
23620b57cec5SDimitry Andric
23630b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_VARIADICS
23640b57cec5SDimitry Andric
23650b57cec5SDimitry Andric// shared_future
23660b57cec5SDimitry Andric
23670b57cec5SDimitry Andrictemplate <class _Rp>
23680b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future
23690b57cec5SDimitry Andric{
23700b57cec5SDimitry Andric    __assoc_state<_Rp>* __state_;
23710b57cec5SDimitry Andric
23720b57cec5SDimitry Andricpublic:
23730b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
23740b57cec5SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
23750b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
23760b57cec5SDimitry Andric    shared_future(const shared_future& __rhs)  _NOEXCEPT : __state_(__rhs.__state_)
23770b57cec5SDimitry Andric        {if (__state_) __state_->__add_shared();}
23780b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
23790b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
23800b57cec5SDimitry Andric    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
23810b57cec5SDimitry Andric        {__f.__state_ = nullptr;}
23820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
23830b57cec5SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
23840b57cec5SDimitry Andric        {__rhs.__state_ = nullptr;}
23850b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
23860b57cec5SDimitry Andric    ~shared_future();
23870b57cec5SDimitry Andric    shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
23880b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
23890b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
23900b57cec5SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
23910b57cec5SDimitry Andric        {
23920b57cec5SDimitry Andric            shared_future(std::move(__rhs)).swap(*this);
23930b57cec5SDimitry Andric            return *this;
23940b57cec5SDimitry Andric        }
23950b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
23960b57cec5SDimitry Andric
23970b57cec5SDimitry Andric    // retrieving the value
23980b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
23990b57cec5SDimitry Andric    const _Rp& get() const {return __state_->copy();}
24000b57cec5SDimitry Andric
24010b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24020b57cec5SDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
24030b57cec5SDimitry Andric
24040b57cec5SDimitry Andric    // functions to check state
24050b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24060b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
24070b57cec5SDimitry Andric
24080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24090b57cec5SDimitry Andric    void wait() const {__state_->wait();}
24100b57cec5SDimitry Andric    template <class _Rep, class _Period>
24110b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
24120b57cec5SDimitry Andric        future_status
24130b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
24140b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
24150b57cec5SDimitry Andric    template <class _Clock, class _Duration>
24160b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
24170b57cec5SDimitry Andric        future_status
24180b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
24190b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
24200b57cec5SDimitry Andric};
24210b57cec5SDimitry Andric
24220b57cec5SDimitry Andrictemplate <class _Rp>
24230b57cec5SDimitry Andricshared_future<_Rp>::~shared_future()
24240b57cec5SDimitry Andric{
24250b57cec5SDimitry Andric    if (__state_)
24260b57cec5SDimitry Andric        __state_->__release_shared();
24270b57cec5SDimitry Andric}
24280b57cec5SDimitry Andric
24290b57cec5SDimitry Andrictemplate <class _Rp>
24300b57cec5SDimitry Andricshared_future<_Rp>&
24310b57cec5SDimitry Andricshared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
24320b57cec5SDimitry Andric{
24330b57cec5SDimitry Andric    if (__rhs.__state_)
24340b57cec5SDimitry Andric        __rhs.__state_->__add_shared();
24350b57cec5SDimitry Andric    if (__state_)
24360b57cec5SDimitry Andric        __state_->__release_shared();
24370b57cec5SDimitry Andric    __state_ = __rhs.__state_;
24380b57cec5SDimitry Andric    return *this;
24390b57cec5SDimitry Andric}
24400b57cec5SDimitry Andric
24410b57cec5SDimitry Andrictemplate <class _Rp>
24420b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
24430b57cec5SDimitry Andric{
24440b57cec5SDimitry Andric    __assoc_state<_Rp&>* __state_;
24450b57cec5SDimitry Andric
24460b57cec5SDimitry Andricpublic:
24470b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24480b57cec5SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
24490b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24500b57cec5SDimitry Andric    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
24510b57cec5SDimitry Andric        {if (__state_) __state_->__add_shared();}
24520b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
24530b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24540b57cec5SDimitry Andric    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
24550b57cec5SDimitry Andric        {__f.__state_ = nullptr;}
24560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24570b57cec5SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
24580b57cec5SDimitry Andric        {__rhs.__state_ = nullptr;}
24590b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
24600b57cec5SDimitry Andric    ~shared_future();
24610b57cec5SDimitry Andric    shared_future& operator=(const shared_future& __rhs);
24620b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
24630b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24640b57cec5SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
24650b57cec5SDimitry Andric        {
24660b57cec5SDimitry Andric            shared_future(std::move(__rhs)).swap(*this);
24670b57cec5SDimitry Andric            return *this;
24680b57cec5SDimitry Andric        }
24690b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
24700b57cec5SDimitry Andric
24710b57cec5SDimitry Andric    // retrieving the value
24720b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24730b57cec5SDimitry Andric    _Rp& get() const {return __state_->copy();}
24740b57cec5SDimitry Andric
24750b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24760b57cec5SDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
24770b57cec5SDimitry Andric
24780b57cec5SDimitry Andric    // functions to check state
24790b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24800b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
24810b57cec5SDimitry Andric
24820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24830b57cec5SDimitry Andric    void wait() const {__state_->wait();}
24840b57cec5SDimitry Andric    template <class _Rep, class _Period>
24850b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
24860b57cec5SDimitry Andric        future_status
24870b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
24880b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
24890b57cec5SDimitry Andric    template <class _Clock, class _Duration>
24900b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
24910b57cec5SDimitry Andric        future_status
24920b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
24930b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
24940b57cec5SDimitry Andric};
24950b57cec5SDimitry Andric
24960b57cec5SDimitry Andrictemplate <class _Rp>
24970b57cec5SDimitry Andricshared_future<_Rp&>::~shared_future()
24980b57cec5SDimitry Andric{
24990b57cec5SDimitry Andric    if (__state_)
25000b57cec5SDimitry Andric        __state_->__release_shared();
25010b57cec5SDimitry Andric}
25020b57cec5SDimitry Andric
25030b57cec5SDimitry Andrictemplate <class _Rp>
25040b57cec5SDimitry Andricshared_future<_Rp&>&
25050b57cec5SDimitry Andricshared_future<_Rp&>::operator=(const shared_future& __rhs)
25060b57cec5SDimitry Andric{
25070b57cec5SDimitry Andric    if (__rhs.__state_)
25080b57cec5SDimitry Andric        __rhs.__state_->__add_shared();
25090b57cec5SDimitry Andric    if (__state_)
25100b57cec5SDimitry Andric        __state_->__release_shared();
25110b57cec5SDimitry Andric    __state_ = __rhs.__state_;
25120b57cec5SDimitry Andric    return *this;
25130b57cec5SDimitry Andric}
25140b57cec5SDimitry Andric
25150b57cec5SDimitry Andrictemplate <>
25160b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
25170b57cec5SDimitry Andric{
25180b57cec5SDimitry Andric    __assoc_sub_state* __state_;
25190b57cec5SDimitry Andric
25200b57cec5SDimitry Andricpublic:
25210b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25220b57cec5SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
25230b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25240b57cec5SDimitry Andric    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
25250b57cec5SDimitry Andric        {if (__state_) __state_->__add_shared();}
25260b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
25270b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25280b57cec5SDimitry Andric    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
25290b57cec5SDimitry Andric        {__f.__state_ = nullptr;}
25300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25310b57cec5SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
25320b57cec5SDimitry Andric        {__rhs.__state_ = nullptr;}
25330b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
25340b57cec5SDimitry Andric    ~shared_future();
25350b57cec5SDimitry Andric    shared_future& operator=(const shared_future& __rhs);
25360b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
25370b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25380b57cec5SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
25390b57cec5SDimitry Andric        {
25400b57cec5SDimitry Andric            shared_future(std::move(__rhs)).swap(*this);
25410b57cec5SDimitry Andric            return *this;
25420b57cec5SDimitry Andric        }
25430b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
25440b57cec5SDimitry Andric
25450b57cec5SDimitry Andric    // retrieving the value
25460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25470b57cec5SDimitry Andric    void get() const {__state_->copy();}
25480b57cec5SDimitry Andric
25490b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25500b57cec5SDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
25510b57cec5SDimitry Andric
25520b57cec5SDimitry Andric    // functions to check state
25530b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25540b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
25550b57cec5SDimitry Andric
25560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25570b57cec5SDimitry Andric    void wait() const {__state_->wait();}
25580b57cec5SDimitry Andric    template <class _Rep, class _Period>
25590b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
25600b57cec5SDimitry Andric        future_status
25610b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
25620b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
25630b57cec5SDimitry Andric    template <class _Clock, class _Duration>
25640b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
25650b57cec5SDimitry Andric        future_status
25660b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
25670b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
25680b57cec5SDimitry Andric};
25690b57cec5SDimitry Andric
25700b57cec5SDimitry Andrictemplate <class _Rp>
25710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
25720b57cec5SDimitry Andricvoid
25730b57cec5SDimitry Andricswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
25740b57cec5SDimitry Andric{
25750b57cec5SDimitry Andric    __x.swap(__y);
25760b57cec5SDimitry Andric}
25770b57cec5SDimitry Andric
25780b57cec5SDimitry Andrictemplate <class _Rp>
25790b57cec5SDimitry Andricinline
25800b57cec5SDimitry Andricshared_future<_Rp>
25810b57cec5SDimitry Andricfuture<_Rp>::share() _NOEXCEPT
25820b57cec5SDimitry Andric{
25830b57cec5SDimitry Andric    return shared_future<_Rp>(_VSTD::move(*this));
25840b57cec5SDimitry Andric}
25850b57cec5SDimitry Andric
25860b57cec5SDimitry Andrictemplate <class _Rp>
25870b57cec5SDimitry Andricinline
25880b57cec5SDimitry Andricshared_future<_Rp&>
25890b57cec5SDimitry Andricfuture<_Rp&>::share() _NOEXCEPT
25900b57cec5SDimitry Andric{
25910b57cec5SDimitry Andric    return shared_future<_Rp&>(_VSTD::move(*this));
25920b57cec5SDimitry Andric}
25930b57cec5SDimitry Andric
25940b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
25950b57cec5SDimitry Andric
25960b57cec5SDimitry Andricinline
25970b57cec5SDimitry Andricshared_future<void>
25980b57cec5SDimitry Andricfuture<void>::share() _NOEXCEPT
25990b57cec5SDimitry Andric{
26000b57cec5SDimitry Andric    return shared_future<void>(_VSTD::move(*this));
26010b57cec5SDimitry Andric}
26020b57cec5SDimitry Andric
26030b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
26040b57cec5SDimitry Andric
26050b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
26060b57cec5SDimitry Andric
26070b57cec5SDimitry Andric#endif // !_LIBCPP_HAS_NO_THREADS
26080b57cec5SDimitry Andric
26090b57cec5SDimitry Andric#endif  // _LIBCPP_FUTURE
2610