10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
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
475f757f3fSDimitry Andricclass future_error : public logic_error {
480b57cec5SDimitry Andricpublic:
495f757f3fSDimitry Andric    explicit future_error(future_errc e); // since C++17
505f757f3fSDimitry Andric
510b57cec5SDimitry Andric    const error_code& code() const noexcept;
520b57cec5SDimitry Andric    const char*       what() const noexcept;
535f757f3fSDimitry Andric
545f757f3fSDimitry Andricprivate:
555f757f3fSDimitry Andric    error_code ec_;             // exposition only
560b57cec5SDimitry Andric};
570b57cec5SDimitry Andric
580b57cec5SDimitry Andrictemplate <class R>
590b57cec5SDimitry Andricclass promise
600b57cec5SDimitry Andric{
610b57cec5SDimitry Andricpublic:
620b57cec5SDimitry Andric    promise();
630b57cec5SDimitry Andric    template <class Allocator>
640b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
650b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
660b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
670b57cec5SDimitry Andric    ~promise();
680b57cec5SDimitry Andric
690b57cec5SDimitry Andric    // assignment
700b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
710b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
720b57cec5SDimitry Andric    void swap(promise& other) noexcept;
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric    // retrieving the result
750b57cec5SDimitry Andric    future<R> get_future();
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric    // setting the result
780b57cec5SDimitry Andric    void set_value(const R& r);
790b57cec5SDimitry Andric    void set_value(R&& r);
800b57cec5SDimitry Andric    void set_exception(exception_ptr p);
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric    // setting the result with deferred notification
830b57cec5SDimitry Andric    void set_value_at_thread_exit(const R& r);
840b57cec5SDimitry Andric    void set_value_at_thread_exit(R&& r);
850b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
860b57cec5SDimitry Andric};
870b57cec5SDimitry Andric
880b57cec5SDimitry Andrictemplate <class R>
890b57cec5SDimitry Andricclass promise<R&>
900b57cec5SDimitry Andric{
910b57cec5SDimitry Andricpublic:
920b57cec5SDimitry Andric    promise();
930b57cec5SDimitry Andric    template <class Allocator>
940b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
950b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
960b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
970b57cec5SDimitry Andric    ~promise();
980b57cec5SDimitry Andric
990b57cec5SDimitry Andric    // assignment
1000b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
1010b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
1020b57cec5SDimitry Andric    void swap(promise& other) noexcept;
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andric    // retrieving the result
1050b57cec5SDimitry Andric    future<R&> get_future();
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric    // setting the result
1080b57cec5SDimitry Andric    void set_value(R& r);
1090b57cec5SDimitry Andric    void set_exception(exception_ptr p);
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andric    // setting the result with deferred notification
1120b57cec5SDimitry Andric    void set_value_at_thread_exit(R&);
1130b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
1140b57cec5SDimitry Andric};
1150b57cec5SDimitry Andric
1160b57cec5SDimitry Andrictemplate <>
1170b57cec5SDimitry Andricclass promise<void>
1180b57cec5SDimitry Andric{
1190b57cec5SDimitry Andricpublic:
1200b57cec5SDimitry Andric    promise();
1210b57cec5SDimitry Andric    template <class Allocator>
1220b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
1230b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
1240b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
1250b57cec5SDimitry Andric    ~promise();
1260b57cec5SDimitry Andric
1270b57cec5SDimitry Andric    // assignment
1280b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
1290b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
1300b57cec5SDimitry Andric    void swap(promise& other) noexcept;
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric    // retrieving the result
1330b57cec5SDimitry Andric    future<void> get_future();
1340b57cec5SDimitry Andric
1350b57cec5SDimitry Andric    // setting the result
1360b57cec5SDimitry Andric    void set_value();
1370b57cec5SDimitry Andric    void set_exception(exception_ptr p);
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andric    // setting the result with deferred notification
1400b57cec5SDimitry Andric    void set_value_at_thread_exit();
1410b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
1420b57cec5SDimitry Andric};
1430b57cec5SDimitry Andric
1440b57cec5SDimitry Andrictemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andrictemplate <class R, class Alloc>
1470b57cec5SDimitry Andric    struct uses_allocator<promise<R>, Alloc> : public true_type {};
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andrictemplate <class R>
1500b57cec5SDimitry Andricclass future
1510b57cec5SDimitry Andric{
1520b57cec5SDimitry Andricpublic:
1530b57cec5SDimitry Andric    future() noexcept;
1540b57cec5SDimitry Andric    future(future&&) noexcept;
1550b57cec5SDimitry Andric    future(const future& rhs) = delete;
1560b57cec5SDimitry Andric    ~future();
1570b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
1580b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
1590b57cec5SDimitry Andric    shared_future<R> share() noexcept;
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric    // retrieving the value
1620b57cec5SDimitry Andric    R get();
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric    // functions to check state
1650b57cec5SDimitry Andric    bool valid() const noexcept;
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andric    void wait() const;
1680b57cec5SDimitry Andric    template <class Rep, class Period>
1690b57cec5SDimitry Andric        future_status
1700b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
1710b57cec5SDimitry Andric    template <class Clock, class Duration>
1720b57cec5SDimitry Andric        future_status
1730b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
1740b57cec5SDimitry Andric};
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andrictemplate <class R>
1770b57cec5SDimitry Andricclass future<R&>
1780b57cec5SDimitry Andric{
1790b57cec5SDimitry Andricpublic:
1800b57cec5SDimitry Andric    future() noexcept;
1810b57cec5SDimitry Andric    future(future&&) noexcept;
1820b57cec5SDimitry Andric    future(const future& rhs) = delete;
1830b57cec5SDimitry Andric    ~future();
1840b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
1850b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
1860b57cec5SDimitry Andric    shared_future<R&> share() noexcept;
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andric    // retrieving the value
1890b57cec5SDimitry Andric    R& get();
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andric    // functions to check state
1920b57cec5SDimitry Andric    bool valid() const noexcept;
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric    void wait() const;
1950b57cec5SDimitry Andric    template <class Rep, class Period>
1960b57cec5SDimitry Andric        future_status
1970b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
1980b57cec5SDimitry Andric    template <class Clock, class Duration>
1990b57cec5SDimitry Andric        future_status
2000b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2010b57cec5SDimitry Andric};
2020b57cec5SDimitry Andric
2030b57cec5SDimitry Andrictemplate <>
2040b57cec5SDimitry Andricclass future<void>
2050b57cec5SDimitry Andric{
2060b57cec5SDimitry Andricpublic:
2070b57cec5SDimitry Andric    future() noexcept;
2080b57cec5SDimitry Andric    future(future&&) noexcept;
2090b57cec5SDimitry Andric    future(const future& rhs) = delete;
2100b57cec5SDimitry Andric    ~future();
2110b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
2120b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
2130b57cec5SDimitry Andric    shared_future<void> share() noexcept;
2140b57cec5SDimitry Andric
2150b57cec5SDimitry Andric    // retrieving the value
2160b57cec5SDimitry Andric    void get();
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric    // functions to check state
2190b57cec5SDimitry Andric    bool valid() const noexcept;
2200b57cec5SDimitry Andric
2210b57cec5SDimitry Andric    void wait() const;
2220b57cec5SDimitry Andric    template <class Rep, class Period>
2230b57cec5SDimitry Andric        future_status
2240b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2250b57cec5SDimitry Andric    template <class Clock, class Duration>
2260b57cec5SDimitry Andric        future_status
2270b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2280b57cec5SDimitry Andric};
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andrictemplate <class R>
2310b57cec5SDimitry Andricclass shared_future
2320b57cec5SDimitry Andric{
2330b57cec5SDimitry Andricpublic:
2340b57cec5SDimitry Andric    shared_future() noexcept;
2350b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2360b57cec5SDimitry Andric    shared_future(future<R>&&) noexcept;
2370b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2380b57cec5SDimitry Andric    ~shared_future();
2390b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2400b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andric    // retrieving the value
2430b57cec5SDimitry Andric    const R& get() const;
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric    // functions to check state
2460b57cec5SDimitry Andric    bool valid() const noexcept;
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andric    void wait() const;
2490b57cec5SDimitry Andric    template <class Rep, class Period>
2500b57cec5SDimitry Andric        future_status
2510b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2520b57cec5SDimitry Andric    template <class Clock, class Duration>
2530b57cec5SDimitry Andric        future_status
2540b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2550b57cec5SDimitry Andric};
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andrictemplate <class R>
2580b57cec5SDimitry Andricclass shared_future<R&>
2590b57cec5SDimitry Andric{
2600b57cec5SDimitry Andricpublic:
2610b57cec5SDimitry Andric    shared_future() noexcept;
2620b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2630b57cec5SDimitry Andric    shared_future(future<R&>&&) noexcept;
2640b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2650b57cec5SDimitry Andric    ~shared_future();
2660b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2670b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric    // retrieving the value
2700b57cec5SDimitry Andric    R& get() const;
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andric    // functions to check state
2730b57cec5SDimitry Andric    bool valid() const noexcept;
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andric    void wait() const;
2760b57cec5SDimitry Andric    template <class Rep, class Period>
2770b57cec5SDimitry Andric        future_status
2780b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2790b57cec5SDimitry Andric    template <class Clock, class Duration>
2800b57cec5SDimitry Andric        future_status
2810b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2820b57cec5SDimitry Andric};
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andrictemplate <>
2850b57cec5SDimitry Andricclass shared_future<void>
2860b57cec5SDimitry Andric{
2870b57cec5SDimitry Andricpublic:
2880b57cec5SDimitry Andric    shared_future() noexcept;
2890b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2900b57cec5SDimitry Andric    shared_future(future<void>&&) noexcept;
2910b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2920b57cec5SDimitry Andric    ~shared_future();
2930b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2940b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andric    // retrieving the value
2970b57cec5SDimitry Andric    void get() const;
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric    // functions to check state
3000b57cec5SDimitry Andric    bool valid() const noexcept;
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andric    void wait() const;
3030b57cec5SDimitry Andric    template <class Rep, class Period>
3040b57cec5SDimitry Andric        future_status
3050b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
3060b57cec5SDimitry Andric    template <class Clock, class Duration>
3070b57cec5SDimitry Andric        future_status
3080b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
3090b57cec5SDimitry Andric};
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andrictemplate <class F, class... Args>
3120b57cec5SDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
3130b57cec5SDimitry Andric  async(F&& f, Args&&... args);
3140b57cec5SDimitry Andric
3150b57cec5SDimitry Andrictemplate <class F, class... Args>
3160b57cec5SDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
3170b57cec5SDimitry Andric  async(launch policy, F&& f, Args&&... args);
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andrictemplate <class> class packaged_task; // undefined
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andrictemplate <class R, class... ArgTypes>
3220b57cec5SDimitry Andricclass packaged_task<R(ArgTypes...)>
3230b57cec5SDimitry Andric{
3240b57cec5SDimitry Andricpublic:
3250b57cec5SDimitry Andric    typedef R result_type; // extension
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric    // construction and destruction
3280b57cec5SDimitry Andric    packaged_task() noexcept;
3290b57cec5SDimitry Andric    template <class F>
3300b57cec5SDimitry Andric        explicit packaged_task(F&& f);
3310b57cec5SDimitry Andric    template <class F, class Allocator>
3320b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const Allocator& a, F&& f);
3330b57cec5SDimitry Andric    ~packaged_task();
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric    // no copy
3360b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
3370b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andric    // move support
3400b57cec5SDimitry Andric    packaged_task(packaged_task&& other) noexcept;
3410b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& other) noexcept;
3420b57cec5SDimitry Andric    void swap(packaged_task& other) noexcept;
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andric    bool valid() const noexcept;
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andric    // result retrieval
3470b57cec5SDimitry Andric    future<R> get_future();
3480b57cec5SDimitry Andric
3490b57cec5SDimitry Andric    // execution
3500b57cec5SDimitry Andric    void operator()(ArgTypes... );
3510b57cec5SDimitry Andric    void make_ready_at_thread_exit(ArgTypes...);
3520b57cec5SDimitry Andric
3530b57cec5SDimitry Andric    void reset();
3540b57cec5SDimitry Andric};
3550b57cec5SDimitry Andric
3560b57cec5SDimitry Andrictemplate <class R>
3570b57cec5SDimitry Andric  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andrictemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
3600b57cec5SDimitry Andric
3610b57cec5SDimitry Andric}  // std
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andric*/
3640b57cec5SDimitry Andric
3657a6dacacSDimitry Andric#include <__config>
3667a6dacacSDimitry Andric
3677a6dacacSDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
3687a6dacacSDimitry Andric#  error "<future> is not supported since libc++ has been configured without support for threads."
3697a6dacacSDimitry Andric#endif
3707a6dacacSDimitry Andric
37181ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
372e8d8bef9SDimitry Andric#include <__availability>
37381ad6265SDimitry Andric#include <__chrono/duration.h>
37481ad6265SDimitry Andric#include <__chrono/time_point.h>
37506c3fb27SDimitry Andric#include <__exception/exception_ptr.h>
37606c3fb27SDimitry Andric#include <__memory/addressof.h>
37706c3fb27SDimitry Andric#include <__memory/allocator.h>
378fe6060f1SDimitry Andric#include <__memory/allocator_arg_t.h>
379bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h>
38006c3fb27SDimitry Andric#include <__memory/allocator_traits.h>
38106c3fb27SDimitry Andric#include <__memory/compressed_pair.h>
38206c3fb27SDimitry Andric#include <__memory/pointer_traits.h>
38306c3fb27SDimitry Andric#include <__memory/shared_ptr.h>
38406c3fb27SDimitry Andric#include <__memory/unique_ptr.h>
385fe6060f1SDimitry Andric#include <__memory/uses_allocator.h>
38606c3fb27SDimitry Andric#include <__system_error/error_category.h>
38706c3fb27SDimitry Andric#include <__system_error/error_code.h>
38806c3fb27SDimitry Andric#include <__system_error/error_condition.h>
38906c3fb27SDimitry Andric#include <__type_traits/aligned_storage.h>
390bdd1243dSDimitry Andric#include <__type_traits/strip_signature.h>
3910eae32dcSDimitry Andric#include <__utility/auto_cast.h>
392fe6060f1SDimitry Andric#include <__utility/forward.h>
39381ad6265SDimitry Andric#include <__utility/move.h>
3940b57cec5SDimitry Andric#include <mutex>
395bdd1243dSDimitry Andric#include <new>
39606c3fb27SDimitry Andric#include <stdexcept>
3970b57cec5SDimitry Andric#include <thread>
39804eeddc0SDimitry Andric#include <version>
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4010b57cec5SDimitry Andric#  pragma GCC system_header
4020b57cec5SDimitry Andric#endif
4030b57cec5SDimitry Andric
404b3edf446SDimitry Andric_LIBCPP_PUSH_MACROS
405b3edf446SDimitry Andric#include <__undef_macros>
406b3edf446SDimitry Andric
4070b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
4080b57cec5SDimitry Andric
4090b57cec5SDimitry Andric// enum class future_errc
410cb14a3feSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_errc){
411cb14a3feSDimitry Andric    future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise};
4120b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
4130b57cec5SDimitry Andric
4140b57cec5SDimitry Andrictemplate <>
4150b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
4160b57cec5SDimitry Andric
41781ad6265SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
4180b57cec5SDimitry Andrictemplate <>
4190b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type {};
4200b57cec5SDimitry Andric#endif
4210b57cec5SDimitry Andric
4220b57cec5SDimitry Andric// enum class launch
423cb14a3feSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(launch){async = 1, deferred = 2, any = async | deferred};
4240b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
4250b57cec5SDimitry Andric
42681ad6265SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
4270b57cec5SDimitry Andric
4280b57cec5SDimitry Andrictypedef underlying_type<launch>::type __launch_underlying_type;
4290b57cec5SDimitry Andric
430cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR launch operator&(launch __x, launch __y) {
431cb14a3feSDimitry Andric  return static_cast<launch>(static_cast<__launch_underlying_type>(__x) & static_cast<__launch_underlying_type>(__y));
4320b57cec5SDimitry Andric}
4330b57cec5SDimitry Andric
434cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR launch operator|(launch __x, launch __y) {
435cb14a3feSDimitry Andric  return static_cast<launch>(static_cast<__launch_underlying_type>(__x) | static_cast<__launch_underlying_type>(__y));
4360b57cec5SDimitry Andric}
4370b57cec5SDimitry Andric
438cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR launch operator^(launch __x, launch __y) {
439cb14a3feSDimitry Andric  return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^ static_cast<__launch_underlying_type>(__y));
4400b57cec5SDimitry Andric}
4410b57cec5SDimitry Andric
442cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR launch operator~(launch __x) {
4430b57cec5SDimitry Andric  return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
4440b57cec5SDimitry Andric}
4450b57cec5SDimitry Andric
446cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI launch& operator&=(launch& __x, launch __y) {
447cb14a3feSDimitry Andric  __x = __x & __y;
448cb14a3feSDimitry Andric  return __x;
4490b57cec5SDimitry Andric}
4500b57cec5SDimitry Andric
451cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI launch& operator|=(launch& __x, launch __y) {
452cb14a3feSDimitry Andric  __x = __x | __y;
453cb14a3feSDimitry Andric  return __x;
4540b57cec5SDimitry Andric}
4550b57cec5SDimitry Andric
456cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI launch& operator^=(launch& __x, launch __y) {
457cb14a3feSDimitry Andric  __x = __x ^ __y;
458cb14a3feSDimitry Andric  return __x;
4590b57cec5SDimitry Andric}
4600b57cec5SDimitry Andric
46181ad6265SDimitry Andric#endif // !_LIBCPP_CXX03_LANG
4620b57cec5SDimitry Andric
4630b57cec5SDimitry Andric// enum class future_status
464cb14a3feSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_status){ready, timeout, deferred};
4650b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
4660b57cec5SDimitry Andric
46706c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;
4680b57cec5SDimitry Andric
469cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(future_errc __e) _NOEXCEPT {
4700b57cec5SDimitry Andric  return error_code(static_cast<int>(__e), future_category());
4710b57cec5SDimitry Andric}
4720b57cec5SDimitry Andric
473cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(future_errc __e) _NOEXCEPT {
4740b57cec5SDimitry Andric  return error_condition(static_cast<int>(__e), future_category());
4750b57cec5SDimitry Andric}
4760b57cec5SDimitry Andric
4775f757f3fSDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_future_error(future_errc __ev);
478fe6060f1SDimitry Andric
4795f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future_error : public logic_error {
4805f757f3fSDimitry Andric  error_code __ec_;
4815f757f3fSDimitry Andric
4825f757f3fSDimitry Andric  future_error(error_code);
4835f757f3fSDimitry Andric  friend void __throw_future_error(future_errc);
484cb14a3feSDimitry Andric  template <class>
485cb14a3feSDimitry Andric  friend class promise;
4865f757f3fSDimitry Andric
4875f757f3fSDimitry Andricpublic:
4885f757f3fSDimitry Andric#if _LIBCPP_STD_VER >= 17
4895f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit future_error(future_errc __ec) : future_error(std::make_error_code(__ec)) {}
4905f757f3fSDimitry Andric#endif
4915f757f3fSDimitry Andric
492cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
4930b57cec5SDimitry Andric
49406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default;
495bdd1243dSDimitry Andric  ~future_error() _NOEXCEPT override;
4960b57cec5SDimitry Andric};
4970b57cec5SDimitry Andric
4985f757f3fSDimitry Andric// Declared above std::future_error
499cb14a3feSDimitry Andricvoid __throw_future_error(future_errc __ev) {
50006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
501753f127fSDimitry Andric  throw future_error(make_error_code(__ev));
5020b57cec5SDimitry Andric#else
50306c3fb27SDimitry Andric  (void)__ev;
50406c3fb27SDimitry Andric  _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode");
5050b57cec5SDimitry Andric#endif
5060b57cec5SDimitry Andric}
5070b57cec5SDimitry Andric
5085f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI __assoc_sub_state : public __shared_count {
5090b57cec5SDimitry Andricprotected:
5100b57cec5SDimitry Andric  exception_ptr __exception_;
5110b57cec5SDimitry Andric  mutable mutex __mut_;
5120b57cec5SDimitry Andric  mutable condition_variable __cv_;
5130b57cec5SDimitry Andric  unsigned __state_;
5140b57cec5SDimitry Andric
515bdd1243dSDimitry Andric  void __on_zero_shared() _NOEXCEPT override;
5160b57cec5SDimitry Andric  void __sub_wait(unique_lock<mutex>& __lk);
517cb14a3feSDimitry Andric
5180b57cec5SDimitry Andricpublic:
519cb14a3feSDimitry Andric  enum { __constructed = 1, __future_attached = 2, ready = 4, deferred = 8 };
5200b57cec5SDimitry Andric
521cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __assoc_sub_state() : __state_(0) {}
5220b57cec5SDimitry Andric
523cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool __has_value() const { return (__state_ & __constructed) || (__exception_ != nullptr); }
5240b57cec5SDimitry Andric
525cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __attach_future() {
5260b57cec5SDimitry Andric    lock_guard<mutex> __lk(__mut_);
5270b57cec5SDimitry Andric    bool __has_future_attached = (__state_ & __future_attached) != 0;
5280b57cec5SDimitry Andric    if (__has_future_attached)
5290b57cec5SDimitry Andric      __throw_future_error(future_errc::future_already_retrieved);
5300b57cec5SDimitry Andric    this->__add_shared();
5310b57cec5SDimitry Andric    __state_ |= __future_attached;
5320b57cec5SDimitry Andric  }
5330b57cec5SDimitry Andric
534cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __set_deferred() { __state_ |= deferred; }
5350b57cec5SDimitry Andric
5360b57cec5SDimitry Andric  void __make_ready();
537cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool __is_ready() const { return (__state_ & ready) != 0; }
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric  void set_value();
5400b57cec5SDimitry Andric  void set_value_at_thread_exit();
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andric  void set_exception(exception_ptr __p);
5430b57cec5SDimitry Andric  void set_exception_at_thread_exit(exception_ptr __p);
5440b57cec5SDimitry Andric
5450b57cec5SDimitry Andric  void copy();
5460b57cec5SDimitry Andric
5470b57cec5SDimitry Andric  void wait();
5480b57cec5SDimitry Andric  template <class _Rep, class _Period>
549cb14a3feSDimitry Andric  future_status _LIBCPP_HIDE_FROM_ABI wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
5500b57cec5SDimitry Andric  template <class _Clock, class _Duration>
551cb14a3feSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS future_status
5520b57cec5SDimitry Andric  wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andric  virtual void __execute();
5550b57cec5SDimitry Andric};
5560b57cec5SDimitry Andric
5570b57cec5SDimitry Andrictemplate <class _Clock, class _Duration>
558cb14a3feSDimitry Andricfuture_status __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
5590b57cec5SDimitry Andric  unique_lock<mutex> __lk(__mut_);
5600b57cec5SDimitry Andric  if (__state_ & deferred)
5610b57cec5SDimitry Andric    return future_status::deferred;
5620b57cec5SDimitry Andric  while (!(__state_ & ready) && _Clock::now() < __abs_time)
5630b57cec5SDimitry Andric    __cv_.wait_until(__lk, __abs_time);
5640b57cec5SDimitry Andric  if (__state_ & ready)
5650b57cec5SDimitry Andric    return future_status::ready;
5660b57cec5SDimitry Andric  return future_status::timeout;
5670b57cec5SDimitry Andric}
5680b57cec5SDimitry Andric
5690b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
570cb14a3feSDimitry Andricinline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
5710b57cec5SDimitry Andric  return wait_until(chrono::steady_clock::now() + __rel_time);
5720b57cec5SDimitry Andric}
5730b57cec5SDimitry Andric
5740b57cec5SDimitry Andrictemplate <class _Rp>
575cb14a3feSDimitry Andricclass _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state {
5760b57cec5SDimitry Andric  typedef __assoc_sub_state base;
577bdd1243dSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
5785f757f3fSDimitry Andric  typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up;
579bdd1243dSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_POP
580cb14a3feSDimitry Andric
5810b57cec5SDimitry Andricprotected:
5820b57cec5SDimitry Andric  _Up __value_;
5830b57cec5SDimitry Andric
58406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
5850b57cec5SDimitry Andric
586cb14a3feSDimitry Andricpublic:
5870b57cec5SDimitry Andric  template <class _Arg>
58806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg);
5890b57cec5SDimitry Andric
5900b57cec5SDimitry Andric  template <class _Arg>
59106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg);
5920b57cec5SDimitry Andric
59306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp move();
59406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy();
5950b57cec5SDimitry Andric};
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andrictemplate <class _Rp>
598cb14a3feSDimitry Andricvoid __assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT {
5990b57cec5SDimitry Andric  if (this->__state_ & base::__constructed)
6000b57cec5SDimitry Andric    reinterpret_cast<_Rp*>(&__value_)->~_Rp();
6010b57cec5SDimitry Andric  delete this;
6020b57cec5SDimitry Andric}
6030b57cec5SDimitry Andric
6040b57cec5SDimitry Andrictemplate <class _Rp>
6050b57cec5SDimitry Andrictemplate <class _Arg>
606cb14a3feSDimitry Andricvoid __assoc_state<_Rp>::set_value(_Arg&& __arg) {
6070b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6080b57cec5SDimitry Andric  if (this->__has_value())
6090b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6105f757f3fSDimitry Andric  ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
6110b57cec5SDimitry Andric  this->__state_ |= base::__constructed | base::ready;
6120b57cec5SDimitry Andric  __cv_.notify_all();
6130b57cec5SDimitry Andric}
6140b57cec5SDimitry Andric
6150b57cec5SDimitry Andrictemplate <class _Rp>
6160b57cec5SDimitry Andrictemplate <class _Arg>
617cb14a3feSDimitry Andricvoid __assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) {
6180b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6190b57cec5SDimitry Andric  if (this->__has_value())
6200b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6215f757f3fSDimitry Andric  ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
6220b57cec5SDimitry Andric  this->__state_ |= base::__constructed;
6230b57cec5SDimitry Andric  __thread_local_data()->__make_ready_at_thread_exit(this);
6240b57cec5SDimitry Andric}
6250b57cec5SDimitry Andric
6260b57cec5SDimitry Andrictemplate <class _Rp>
627cb14a3feSDimitry Andric_Rp __assoc_state<_Rp>::move() {
6280b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6290b57cec5SDimitry Andric  this->__sub_wait(__lk);
6300b57cec5SDimitry Andric  if (this->__exception_ != nullptr)
631bdd1243dSDimitry Andric    std::rethrow_exception(this->__exception_);
6325f757f3fSDimitry Andric  return std::move(*reinterpret_cast<_Rp*>(&__value_));
6330b57cec5SDimitry Andric}
6340b57cec5SDimitry Andric
6350b57cec5SDimitry Andrictemplate <class _Rp>
636cb14a3feSDimitry Andric__add_lvalue_reference_t<_Rp> __assoc_state<_Rp>::copy() {
6370b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6380b57cec5SDimitry Andric  this->__sub_wait(__lk);
6390b57cec5SDimitry Andric  if (this->__exception_ != nullptr)
640bdd1243dSDimitry Andric    std::rethrow_exception(this->__exception_);
6410b57cec5SDimitry Andric  return *reinterpret_cast<_Rp*>(&__value_);
6420b57cec5SDimitry Andric}
6430b57cec5SDimitry Andric
6440b57cec5SDimitry Andrictemplate <class _Rp>
645cb14a3feSDimitry Andricclass __assoc_state<_Rp&> : public __assoc_sub_state {
6460b57cec5SDimitry Andric  typedef __assoc_sub_state base;
6470b57cec5SDimitry Andric  typedef _Rp* _Up;
648cb14a3feSDimitry Andric
6490b57cec5SDimitry Andricprotected:
6500b57cec5SDimitry Andric  _Up __value_;
6510b57cec5SDimitry Andric
65206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
6530b57cec5SDimitry Andric
654cb14a3feSDimitry Andricpublic:
65506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg);
65606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg);
6570b57cec5SDimitry Andric
65806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& copy();
6590b57cec5SDimitry Andric};
6600b57cec5SDimitry Andric
6610b57cec5SDimitry Andrictemplate <class _Rp>
662cb14a3feSDimitry Andricvoid __assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT {
6630b57cec5SDimitry Andric  delete this;
6640b57cec5SDimitry Andric}
6650b57cec5SDimitry Andric
6660b57cec5SDimitry Andrictemplate <class _Rp>
667cb14a3feSDimitry Andricvoid __assoc_state<_Rp&>::set_value(_Rp& __arg) {
6680b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6690b57cec5SDimitry Andric  if (this->__has_value())
6700b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6715f757f3fSDimitry Andric  __value_ = std::addressof(__arg);
6720b57cec5SDimitry Andric  this->__state_ |= base::__constructed | base::ready;
6730b57cec5SDimitry Andric  __cv_.notify_all();
6740b57cec5SDimitry Andric}
6750b57cec5SDimitry Andric
6760b57cec5SDimitry Andrictemplate <class _Rp>
677cb14a3feSDimitry Andricvoid __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) {
6780b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6790b57cec5SDimitry Andric  if (this->__has_value())
6800b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6815f757f3fSDimitry Andric  __value_ = std::addressof(__arg);
6820b57cec5SDimitry Andric  this->__state_ |= base::__constructed;
6830b57cec5SDimitry Andric  __thread_local_data()->__make_ready_at_thread_exit(this);
6840b57cec5SDimitry Andric}
6850b57cec5SDimitry Andric
6860b57cec5SDimitry Andrictemplate <class _Rp>
687cb14a3feSDimitry Andric_Rp& __assoc_state<_Rp&>::copy() {
6880b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6890b57cec5SDimitry Andric  this->__sub_wait(__lk);
6900b57cec5SDimitry Andric  if (this->__exception_ != nullptr)
691bdd1243dSDimitry Andric    std::rethrow_exception(this->__exception_);
6920b57cec5SDimitry Andric  return *__value_;
6930b57cec5SDimitry Andric}
6940b57cec5SDimitry Andric
6950b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
696cb14a3feSDimitry Andricclass __assoc_state_alloc : public __assoc_state<_Rp> {
6970b57cec5SDimitry Andric  typedef __assoc_state<_Rp> base;
6980b57cec5SDimitry Andric  _Alloc __alloc_;
6990b57cec5SDimitry Andric
70006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
701cb14a3feSDimitry Andric
7020b57cec5SDimitry Andricpublic:
703cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
7040b57cec5SDimitry Andric};
7050b57cec5SDimitry Andric
7060b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
707cb14a3feSDimitry Andricvoid __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT {
7080b57cec5SDimitry Andric  if (this->__state_ & base::__constructed)
7095f757f3fSDimitry Andric    reinterpret_cast<_Rp*>(std::addressof(this->__value_))->~_Rp();
7100b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
7110b57cec5SDimitry Andric  typedef allocator_traits<_Al> _ATraits;
7120b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7130b57cec5SDimitry Andric  _Al __a(__alloc_);
7140b57cec5SDimitry Andric  this->~__assoc_state_alloc();
7150b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
7160b57cec5SDimitry Andric}
7170b57cec5SDimitry Andric
7180b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
719cb14a3feSDimitry Andricclass __assoc_state_alloc<_Rp&, _Alloc> : public __assoc_state<_Rp&> {
7200b57cec5SDimitry Andric  typedef __assoc_state<_Rp&> base;
7210b57cec5SDimitry Andric  _Alloc __alloc_;
7220b57cec5SDimitry Andric
72306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
724cb14a3feSDimitry Andric
7250b57cec5SDimitry Andricpublic:
726cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
7270b57cec5SDimitry Andric};
7280b57cec5SDimitry Andric
7290b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
730cb14a3feSDimitry Andricvoid __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT {
7310b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
7320b57cec5SDimitry Andric  typedef allocator_traits<_Al> _ATraits;
7330b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7340b57cec5SDimitry Andric  _Al __a(__alloc_);
7350b57cec5SDimitry Andric  this->~__assoc_state_alloc();
7360b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
7370b57cec5SDimitry Andric}
7380b57cec5SDimitry Andric
7390b57cec5SDimitry Andrictemplate <class _Alloc>
740cb14a3feSDimitry Andricclass __assoc_sub_state_alloc : public __assoc_sub_state {
7410b57cec5SDimitry Andric  typedef __assoc_sub_state base;
7420b57cec5SDimitry Andric  _Alloc __alloc_;
7430b57cec5SDimitry Andric
74406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
745cb14a3feSDimitry Andric
7460b57cec5SDimitry Andricpublic:
747cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_sub_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
7480b57cec5SDimitry Andric};
7490b57cec5SDimitry Andric
7500b57cec5SDimitry Andrictemplate <class _Alloc>
751cb14a3feSDimitry Andricvoid __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT {
7520b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
7530b57cec5SDimitry Andric  typedef allocator_traits<_Al> _ATraits;
7540b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7550b57cec5SDimitry Andric  _Al __a(__alloc_);
7560b57cec5SDimitry Andric  this->~__assoc_sub_state_alloc();
7570b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
7580b57cec5SDimitry Andric}
7590b57cec5SDimitry Andric
7600b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
761cb14a3feSDimitry Andricclass __deferred_assoc_state : public __assoc_state<_Rp> {
7620b57cec5SDimitry Andric  typedef __assoc_state<_Rp> base;
7630b57cec5SDimitry Andric
7640b57cec5SDimitry Andric  _Fp __func_;
7650b57cec5SDimitry Andric
7660b57cec5SDimitry Andricpublic:
767cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f);
7680b57cec5SDimitry Andric
76906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
7700b57cec5SDimitry Andric};
7710b57cec5SDimitry Andric
7720b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
773cb14a3feSDimitry Andricinline __deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {
7740b57cec5SDimitry Andric  this->__set_deferred();
7750b57cec5SDimitry Andric}
7760b57cec5SDimitry Andric
7770b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
778cb14a3feSDimitry Andricvoid __deferred_assoc_state<_Rp, _Fp>::__execute() {
77906c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
780cb14a3feSDimitry Andric  try {
78106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
7820b57cec5SDimitry Andric    this->set_value(__func_());
78306c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
784cb14a3feSDimitry Andric  } catch (...) {
7850b57cec5SDimitry Andric    this->set_exception(current_exception());
7860b57cec5SDimitry Andric  }
78706c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
7880b57cec5SDimitry Andric}
7890b57cec5SDimitry Andric
7900b57cec5SDimitry Andrictemplate <class _Fp>
791cb14a3feSDimitry Andricclass __deferred_assoc_state<void, _Fp> : public __assoc_sub_state {
7920b57cec5SDimitry Andric  typedef __assoc_sub_state base;
7930b57cec5SDimitry Andric
7940b57cec5SDimitry Andric  _Fp __func_;
7950b57cec5SDimitry Andric
7960b57cec5SDimitry Andricpublic:
797cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f);
7980b57cec5SDimitry Andric
79906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
8000b57cec5SDimitry Andric};
8010b57cec5SDimitry Andric
8020b57cec5SDimitry Andrictemplate <class _Fp>
803cb14a3feSDimitry Andricinline __deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {
8040b57cec5SDimitry Andric  this->__set_deferred();
8050b57cec5SDimitry Andric}
8060b57cec5SDimitry Andric
8070b57cec5SDimitry Andrictemplate <class _Fp>
808cb14a3feSDimitry Andricvoid __deferred_assoc_state<void, _Fp>::__execute() {
80906c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
810cb14a3feSDimitry Andric  try {
81106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8120b57cec5SDimitry Andric    __func_();
8130b57cec5SDimitry Andric    this->set_value();
81406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
815cb14a3feSDimitry Andric  } catch (...) {
8160b57cec5SDimitry Andric    this->set_exception(current_exception());
8170b57cec5SDimitry Andric  }
81806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8190b57cec5SDimitry Andric}
8200b57cec5SDimitry Andric
8210b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
822cb14a3feSDimitry Andricclass __async_assoc_state : public __assoc_state<_Rp> {
8230b57cec5SDimitry Andric  typedef __assoc_state<_Rp> base;
8240b57cec5SDimitry Andric
8250b57cec5SDimitry Andric  _Fp __func_;
8260b57cec5SDimitry Andric
82706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
828cb14a3feSDimitry Andric
8290b57cec5SDimitry Andricpublic:
830cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f);
8310b57cec5SDimitry Andric
83206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
8330b57cec5SDimitry Andric};
8340b57cec5SDimitry Andric
8350b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
836cb14a3feSDimitry Andricinline __async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {}
8370b57cec5SDimitry Andric
8380b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
839cb14a3feSDimitry Andricvoid __async_assoc_state<_Rp, _Fp>::__execute() {
84006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
841cb14a3feSDimitry Andric  try {
84206c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8430b57cec5SDimitry Andric    this->set_value(__func_());
84406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
845cb14a3feSDimitry Andric  } catch (...) {
8460b57cec5SDimitry Andric    this->set_exception(current_exception());
8470b57cec5SDimitry Andric  }
84806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8490b57cec5SDimitry Andric}
8500b57cec5SDimitry Andric
8510b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
852cb14a3feSDimitry Andricvoid __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT {
8530b57cec5SDimitry Andric  this->wait();
8540b57cec5SDimitry Andric  base::__on_zero_shared();
8550b57cec5SDimitry Andric}
8560b57cec5SDimitry Andric
8570b57cec5SDimitry Andrictemplate <class _Fp>
858cb14a3feSDimitry Andricclass __async_assoc_state<void, _Fp> : public __assoc_sub_state {
8590b57cec5SDimitry Andric  typedef __assoc_sub_state base;
8600b57cec5SDimitry Andric
8610b57cec5SDimitry Andric  _Fp __func_;
8620b57cec5SDimitry Andric
86306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
864cb14a3feSDimitry Andric
8650b57cec5SDimitry Andricpublic:
866cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f);
8670b57cec5SDimitry Andric
86806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
8690b57cec5SDimitry Andric};
8700b57cec5SDimitry Andric
8710b57cec5SDimitry Andrictemplate <class _Fp>
872cb14a3feSDimitry Andricinline __async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {}
8730b57cec5SDimitry Andric
8740b57cec5SDimitry Andrictemplate <class _Fp>
875cb14a3feSDimitry Andricvoid __async_assoc_state<void, _Fp>::__execute() {
87606c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
877cb14a3feSDimitry Andric  try {
87806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8790b57cec5SDimitry Andric    __func_();
8800b57cec5SDimitry Andric    this->set_value();
88106c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
882cb14a3feSDimitry Andric  } catch (...) {
8830b57cec5SDimitry Andric    this->set_exception(current_exception());
8840b57cec5SDimitry Andric  }
88506c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8860b57cec5SDimitry Andric}
8870b57cec5SDimitry Andric
8880b57cec5SDimitry Andrictemplate <class _Fp>
889cb14a3feSDimitry Andricvoid __async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT {
8900b57cec5SDimitry Andric  this->wait();
8910b57cec5SDimitry Andric  base::__on_zero_shared();
8920b57cec5SDimitry Andric}
8930b57cec5SDimitry Andric
894cb14a3feSDimitry Andrictemplate <class _Rp>
895cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise;
896cb14a3feSDimitry Andrictemplate <class _Rp>
897cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future;
8980b57cec5SDimitry Andric
8990b57cec5SDimitry Andric// future
9000b57cec5SDimitry Andric
901cb14a3feSDimitry Andrictemplate <class _Rp>
902cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future;
9030b57cec5SDimitry Andric
9040b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
905cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f);
9060b57cec5SDimitry Andric
9070b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
908cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f);
9090b57cec5SDimitry Andric
9100b57cec5SDimitry Andrictemplate <class _Rp>
911cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future {
9120b57cec5SDimitry Andric  __assoc_state<_Rp>* __state_;
9130b57cec5SDimitry Andric
91406c3fb27SDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state);
9150b57cec5SDimitry Andric
916cb14a3feSDimitry Andric  template <class>
917cb14a3feSDimitry Andric  friend class promise;
918cb14a3feSDimitry Andric  template <class>
919cb14a3feSDimitry Andric  friend class shared_future;
9200b57cec5SDimitry Andric
9210b57cec5SDimitry Andric  template <class _R1, class _Fp>
9220b57cec5SDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
9230b57cec5SDimitry Andric  template <class _R1, class _Fp>
9240b57cec5SDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
9250b57cec5SDimitry Andric
9260b57cec5SDimitry Andricpublic:
927cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
928cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
9290b57cec5SDimitry Andric  future(const future&)            = delete;
9300b57cec5SDimitry Andric  future& operator=(const future&) = delete;
931cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
9325f757f3fSDimitry Andric    future(std::move(__rhs)).swap(*this);
9330b57cec5SDimitry Andric    return *this;
9340b57cec5SDimitry Andric  }
935e8d8bef9SDimitry Andric
93606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~future();
937cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<_Rp> share() _NOEXCEPT;
9380b57cec5SDimitry Andric
9390b57cec5SDimitry Andric  // retrieving the value
94006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp get();
9410b57cec5SDimitry Andric
942cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
9430b57cec5SDimitry Andric
9440b57cec5SDimitry Andric  // functions to check state
945cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
9460b57cec5SDimitry Andric
947cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
9480b57cec5SDimitry Andric  template <class _Rep, class _Period>
949cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
950cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
951cb14a3feSDimitry Andric  }
9520b57cec5SDimitry Andric  template <class _Clock, class _Duration>
953cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
954cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
955cb14a3feSDimitry Andric  }
9560b57cec5SDimitry Andric};
9570b57cec5SDimitry Andric
9580b57cec5SDimitry Andrictemplate <class _Rp>
959cb14a3feSDimitry Andricfuture<_Rp>::future(__assoc_state<_Rp>* __state) : __state_(__state) {
9600b57cec5SDimitry Andric  __state_->__attach_future();
9610b57cec5SDimitry Andric}
9620b57cec5SDimitry Andric
963cb14a3feSDimitry Andricstruct __release_shared_count {
96406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) { __p->__release_shared(); }
9650b57cec5SDimitry Andric};
9660b57cec5SDimitry Andric
9670b57cec5SDimitry Andrictemplate <class _Rp>
968cb14a3feSDimitry Andricfuture<_Rp>::~future() {
9690b57cec5SDimitry Andric  if (__state_)
9700b57cec5SDimitry Andric    __state_->__release_shared();
9710b57cec5SDimitry Andric}
9720b57cec5SDimitry Andric
9730b57cec5SDimitry Andrictemplate <class _Rp>
974cb14a3feSDimitry Andric_Rp future<_Rp>::get() {
97506c3fb27SDimitry Andric  unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
9760b57cec5SDimitry Andric  __assoc_state<_Rp>* __s = __state_;
9770b57cec5SDimitry Andric  __state_                = nullptr;
9780b57cec5SDimitry Andric  return __s->move();
9790b57cec5SDimitry Andric}
9800b57cec5SDimitry Andric
9810b57cec5SDimitry Andrictemplate <class _Rp>
982cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future<_Rp&> {
9830b57cec5SDimitry Andric  __assoc_state<_Rp&>* __state_;
9840b57cec5SDimitry Andric
98506c3fb27SDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state);
9860b57cec5SDimitry Andric
987cb14a3feSDimitry Andric  template <class>
988cb14a3feSDimitry Andric  friend class promise;
989cb14a3feSDimitry Andric  template <class>
990cb14a3feSDimitry Andric  friend class shared_future;
9910b57cec5SDimitry Andric
9920b57cec5SDimitry Andric  template <class _R1, class _Fp>
9930b57cec5SDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
9940b57cec5SDimitry Andric  template <class _R1, class _Fp>
9950b57cec5SDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
9960b57cec5SDimitry Andric
9970b57cec5SDimitry Andricpublic:
998cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
999cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
10000b57cec5SDimitry Andric  future(const future&)            = delete;
10010b57cec5SDimitry Andric  future& operator=(const future&) = delete;
1002cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
10035f757f3fSDimitry Andric    future(std::move(__rhs)).swap(*this);
10040b57cec5SDimitry Andric    return *this;
10050b57cec5SDimitry Andric  }
1006e8d8bef9SDimitry Andric
100706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~future();
1008cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<_Rp&> share() _NOEXCEPT;
10090b57cec5SDimitry Andric
10100b57cec5SDimitry Andric  // retrieving the value
101106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& get();
10120b57cec5SDimitry Andric
1013cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
10140b57cec5SDimitry Andric
10150b57cec5SDimitry Andric  // functions to check state
1016cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
10170b57cec5SDimitry Andric
1018cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
10190b57cec5SDimitry Andric  template <class _Rep, class _Period>
1020cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1021cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1022cb14a3feSDimitry Andric  }
10230b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1024cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1025cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1026cb14a3feSDimitry Andric  }
10270b57cec5SDimitry Andric};
10280b57cec5SDimitry Andric
10290b57cec5SDimitry Andrictemplate <class _Rp>
1030cb14a3feSDimitry Andricfuture<_Rp&>::future(__assoc_state<_Rp&>* __state) : __state_(__state) {
10310b57cec5SDimitry Andric  __state_->__attach_future();
10320b57cec5SDimitry Andric}
10330b57cec5SDimitry Andric
10340b57cec5SDimitry Andrictemplate <class _Rp>
1035cb14a3feSDimitry Andricfuture<_Rp&>::~future() {
10360b57cec5SDimitry Andric  if (__state_)
10370b57cec5SDimitry Andric    __state_->__release_shared();
10380b57cec5SDimitry Andric}
10390b57cec5SDimitry Andric
10400b57cec5SDimitry Andrictemplate <class _Rp>
1041cb14a3feSDimitry Andric_Rp& future<_Rp&>::get() {
104206c3fb27SDimitry Andric  unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
10430b57cec5SDimitry Andric  __assoc_state<_Rp&>* __s = __state_;
10440b57cec5SDimitry Andric  __state_                 = nullptr;
10450b57cec5SDimitry Andric  return __s->copy();
10460b57cec5SDimitry Andric}
10470b57cec5SDimitry Andric
10480b57cec5SDimitry Andrictemplate <>
1049cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future<void> {
10500b57cec5SDimitry Andric  __assoc_sub_state* __state_;
10510b57cec5SDimitry Andric
10520b57cec5SDimitry Andric  explicit future(__assoc_sub_state* __state);
10530b57cec5SDimitry Andric
1054cb14a3feSDimitry Andric  template <class>
1055cb14a3feSDimitry Andric  friend class promise;
1056cb14a3feSDimitry Andric  template <class>
1057cb14a3feSDimitry Andric  friend class shared_future;
10580b57cec5SDimitry Andric
10590b57cec5SDimitry Andric  template <class _R1, class _Fp>
10600b57cec5SDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
10610b57cec5SDimitry Andric  template <class _R1, class _Fp>
10620b57cec5SDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
10630b57cec5SDimitry Andric
10640b57cec5SDimitry Andricpublic:
1065cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
1066cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
10670b57cec5SDimitry Andric  future(const future&)            = delete;
10680b57cec5SDimitry Andric  future& operator=(const future&) = delete;
1069cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
10705f757f3fSDimitry Andric    future(std::move(__rhs)).swap(*this);
10710b57cec5SDimitry Andric    return *this;
10720b57cec5SDimitry Andric  }
1073e8d8bef9SDimitry Andric
10740b57cec5SDimitry Andric  ~future();
1075cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<void> share() _NOEXCEPT;
10760b57cec5SDimitry Andric
10770b57cec5SDimitry Andric  // retrieving the value
10780b57cec5SDimitry Andric  void get();
10790b57cec5SDimitry Andric
1080cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
10810b57cec5SDimitry Andric
10820b57cec5SDimitry Andric  // functions to check state
1083cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
10840b57cec5SDimitry Andric
1085cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
10860b57cec5SDimitry Andric  template <class _Rep, class _Period>
1087cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1088cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1089cb14a3feSDimitry Andric  }
10900b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1091cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1092cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1093cb14a3feSDimitry Andric  }
10940b57cec5SDimitry Andric};
10950b57cec5SDimitry Andric
10960b57cec5SDimitry Andrictemplate <class _Rp>
1097cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT {
10980b57cec5SDimitry Andric  __x.swap(__y);
10990b57cec5SDimitry Andric}
11000b57cec5SDimitry Andric
11010b57cec5SDimitry Andric// promise<R>
11020b57cec5SDimitry Andric
1103cb14a3feSDimitry Andrictemplate <class _Callable>
1104cb14a3feSDimitry Andricclass packaged_task;
11050b57cec5SDimitry Andric
11060b57cec5SDimitry Andrictemplate <class _Rp>
1107cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise {
11080b57cec5SDimitry Andric  __assoc_state<_Rp>* __state_;
11090b57cec5SDimitry Andric
1110cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
11110b57cec5SDimitry Andric
1112cb14a3feSDimitry Andric  template <class>
1113cb14a3feSDimitry Andric  friend class packaged_task;
1114cb14a3feSDimitry Andric
11150b57cec5SDimitry Andricpublic:
111606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise();
11170b57cec5SDimitry Andric  template <class _Alloc>
111806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a);
1119cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
11200b57cec5SDimitry Andric  promise(const promise& __rhs) = delete;
112106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~promise();
11220b57cec5SDimitry Andric
11230b57cec5SDimitry Andric  // assignment
1124cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
11255f757f3fSDimitry Andric    promise(std::move(__rhs)).swap(*this);
11260b57cec5SDimitry Andric    return *this;
11270b57cec5SDimitry Andric  }
11280b57cec5SDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1129e8d8bef9SDimitry Andric
1130cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andric  // retrieving the result
113306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future();
11340b57cec5SDimitry Andric
11350b57cec5SDimitry Andric  // setting the result
113606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r);
113706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r);
113806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
11390b57cec5SDimitry Andric
11400b57cec5SDimitry Andric  // setting the result with deferred notification
114106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r);
114206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r);
114306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
11440b57cec5SDimitry Andric};
11450b57cec5SDimitry Andric
11460b57cec5SDimitry Andrictemplate <class _Rp>
1147cb14a3feSDimitry Andricpromise<_Rp>::promise() : __state_(new __assoc_state<_Rp>) {}
11480b57cec5SDimitry Andric
11490b57cec5SDimitry Andrictemplate <class _Rp>
11500b57cec5SDimitry Andrictemplate <class _Alloc>
1151cb14a3feSDimitry Andricpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) {
11520b57cec5SDimitry Andric  typedef __assoc_state_alloc<_Rp, _Alloc> _State;
11530b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
11540b57cec5SDimitry Andric  typedef __allocator_destructor<_A2> _D2;
11550b57cec5SDimitry Andric  _A2 __a(__a0);
11560b57cec5SDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
11575f757f3fSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
11585f757f3fSDimitry Andric  __state_ = std::addressof(*__hold.release());
11590b57cec5SDimitry Andric}
11600b57cec5SDimitry Andric
11610b57cec5SDimitry Andrictemplate <class _Rp>
1162cb14a3feSDimitry Andricpromise<_Rp>::~promise() {
1163cb14a3feSDimitry Andric  if (__state_) {
11640b57cec5SDimitry Andric    if (!__state_->__has_value() && __state_->use_count() > 1)
11655f757f3fSDimitry Andric      __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise))));
11660b57cec5SDimitry Andric    __state_->__release_shared();
11670b57cec5SDimitry Andric  }
11680b57cec5SDimitry Andric}
11690b57cec5SDimitry Andric
11700b57cec5SDimitry Andrictemplate <class _Rp>
1171cb14a3feSDimitry Andricfuture<_Rp> promise<_Rp>::get_future() {
11720b57cec5SDimitry Andric  if (__state_ == nullptr)
11730b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11740b57cec5SDimitry Andric  return future<_Rp>(__state_);
11750b57cec5SDimitry Andric}
11760b57cec5SDimitry Andric
11770b57cec5SDimitry Andrictemplate <class _Rp>
1178cb14a3feSDimitry Andricvoid promise<_Rp>::set_value(const _Rp& __r) {
11790b57cec5SDimitry Andric  if (__state_ == nullptr)
11800b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11810b57cec5SDimitry Andric  __state_->set_value(__r);
11820b57cec5SDimitry Andric}
11830b57cec5SDimitry Andric
11840b57cec5SDimitry Andrictemplate <class _Rp>
1185cb14a3feSDimitry Andricvoid promise<_Rp>::set_value(_Rp&& __r) {
11860b57cec5SDimitry Andric  if (__state_ == nullptr)
11870b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11885f757f3fSDimitry Andric  __state_->set_value(std::move(__r));
11890b57cec5SDimitry Andric}
11900b57cec5SDimitry Andric
11910b57cec5SDimitry Andrictemplate <class _Rp>
1192cb14a3feSDimitry Andricvoid promise<_Rp>::set_exception(exception_ptr __p) {
11935f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr");
11940b57cec5SDimitry Andric  if (__state_ == nullptr)
11950b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11960b57cec5SDimitry Andric  __state_->set_exception(__p);
11970b57cec5SDimitry Andric}
11980b57cec5SDimitry Andric
11990b57cec5SDimitry Andrictemplate <class _Rp>
1200cb14a3feSDimitry Andricvoid promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) {
12010b57cec5SDimitry Andric  if (__state_ == nullptr)
12020b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12030b57cec5SDimitry Andric  __state_->set_value_at_thread_exit(__r);
12040b57cec5SDimitry Andric}
12050b57cec5SDimitry Andric
12060b57cec5SDimitry Andrictemplate <class _Rp>
1207cb14a3feSDimitry Andricvoid promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) {
12080b57cec5SDimitry Andric  if (__state_ == nullptr)
12090b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12105f757f3fSDimitry Andric  __state_->set_value_at_thread_exit(std::move(__r));
12110b57cec5SDimitry Andric}
12120b57cec5SDimitry Andric
12130b57cec5SDimitry Andrictemplate <class _Rp>
1214cb14a3feSDimitry Andricvoid promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) {
12155f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr");
12160b57cec5SDimitry Andric  if (__state_ == nullptr)
12170b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12180b57cec5SDimitry Andric  __state_->set_exception_at_thread_exit(__p);
12190b57cec5SDimitry Andric}
12200b57cec5SDimitry Andric
12210b57cec5SDimitry Andric// promise<R&>
12220b57cec5SDimitry Andric
12230b57cec5SDimitry Andrictemplate <class _Rp>
1224cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise<_Rp&> {
12250b57cec5SDimitry Andric  __assoc_state<_Rp&>* __state_;
12260b57cec5SDimitry Andric
1227cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
12280b57cec5SDimitry Andric
1229cb14a3feSDimitry Andric  template <class>
1230cb14a3feSDimitry Andric  friend class packaged_task;
12310b57cec5SDimitry Andric
12320b57cec5SDimitry Andricpublic:
123306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise();
12340b57cec5SDimitry Andric  template <class _Allocator>
123506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a);
1236cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
12370b57cec5SDimitry Andric  promise(const promise& __rhs) = delete;
123806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~promise();
12390b57cec5SDimitry Andric
12400b57cec5SDimitry Andric  // assignment
1241cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
12425f757f3fSDimitry Andric    promise(std::move(__rhs)).swap(*this);
12430b57cec5SDimitry Andric    return *this;
12440b57cec5SDimitry Andric  }
12450b57cec5SDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1246e8d8bef9SDimitry Andric
1247cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
12480b57cec5SDimitry Andric
12490b57cec5SDimitry Andric  // retrieving the result
125006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future();
12510b57cec5SDimitry Andric
12520b57cec5SDimitry Andric  // setting the result
125306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r);
125406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
12550b57cec5SDimitry Andric
12560b57cec5SDimitry Andric  // setting the result with deferred notification
125706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&);
125806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
12590b57cec5SDimitry Andric};
12600b57cec5SDimitry Andric
12610b57cec5SDimitry Andrictemplate <class _Rp>
1262cb14a3feSDimitry Andricpromise<_Rp&>::promise() : __state_(new __assoc_state<_Rp&>) {}
12630b57cec5SDimitry Andric
12640b57cec5SDimitry Andrictemplate <class _Rp>
12650b57cec5SDimitry Andrictemplate <class _Alloc>
1266cb14a3feSDimitry Andricpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) {
12670b57cec5SDimitry Andric  typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
12680b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
12690b57cec5SDimitry Andric  typedef __allocator_destructor<_A2> _D2;
12700b57cec5SDimitry Andric  _A2 __a(__a0);
12710b57cec5SDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
12725f757f3fSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
12735f757f3fSDimitry Andric  __state_ = std::addressof(*__hold.release());
12740b57cec5SDimitry Andric}
12750b57cec5SDimitry Andric
12760b57cec5SDimitry Andrictemplate <class _Rp>
1277cb14a3feSDimitry Andricpromise<_Rp&>::~promise() {
1278cb14a3feSDimitry Andric  if (__state_) {
12790b57cec5SDimitry Andric    if (!__state_->__has_value() && __state_->use_count() > 1)
12805f757f3fSDimitry Andric      __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise))));
12810b57cec5SDimitry Andric    __state_->__release_shared();
12820b57cec5SDimitry Andric  }
12830b57cec5SDimitry Andric}
12840b57cec5SDimitry Andric
12850b57cec5SDimitry Andrictemplate <class _Rp>
1286cb14a3feSDimitry Andricfuture<_Rp&> promise<_Rp&>::get_future() {
12870b57cec5SDimitry Andric  if (__state_ == nullptr)
12880b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12890b57cec5SDimitry Andric  return future<_Rp&>(__state_);
12900b57cec5SDimitry Andric}
12910b57cec5SDimitry Andric
12920b57cec5SDimitry Andrictemplate <class _Rp>
1293cb14a3feSDimitry Andricvoid promise<_Rp&>::set_value(_Rp& __r) {
12940b57cec5SDimitry Andric  if (__state_ == nullptr)
12950b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12960b57cec5SDimitry Andric  __state_->set_value(__r);
12970b57cec5SDimitry Andric}
12980b57cec5SDimitry Andric
12990b57cec5SDimitry Andrictemplate <class _Rp>
1300cb14a3feSDimitry Andricvoid promise<_Rp&>::set_exception(exception_ptr __p) {
13015f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr");
13020b57cec5SDimitry Andric  if (__state_ == nullptr)
13030b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
13040b57cec5SDimitry Andric  __state_->set_exception(__p);
13050b57cec5SDimitry Andric}
13060b57cec5SDimitry Andric
13070b57cec5SDimitry Andrictemplate <class _Rp>
1308cb14a3feSDimitry Andricvoid promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) {
13090b57cec5SDimitry Andric  if (__state_ == nullptr)
13100b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
13110b57cec5SDimitry Andric  __state_->set_value_at_thread_exit(__r);
13120b57cec5SDimitry Andric}
13130b57cec5SDimitry Andric
13140b57cec5SDimitry Andrictemplate <class _Rp>
1315cb14a3feSDimitry Andricvoid promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) {
13165f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr");
13170b57cec5SDimitry Andric  if (__state_ == nullptr)
13180b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
13190b57cec5SDimitry Andric  __state_->set_exception_at_thread_exit(__p);
13200b57cec5SDimitry Andric}
13210b57cec5SDimitry Andric
13220b57cec5SDimitry Andric// promise<void>
13230b57cec5SDimitry Andric
13240b57cec5SDimitry Andrictemplate <>
1325cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI promise<void> {
13260b57cec5SDimitry Andric  __assoc_sub_state* __state_;
13270b57cec5SDimitry Andric
1328cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
13290b57cec5SDimitry Andric
1330cb14a3feSDimitry Andric  template <class>
1331cb14a3feSDimitry Andric  friend class packaged_task;
13320b57cec5SDimitry Andric
13330b57cec5SDimitry Andricpublic:
13340b57cec5SDimitry Andric  promise();
13350b57cec5SDimitry Andric  template <class _Allocator>
1336cb14a3feSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS promise(allocator_arg_t, const _Allocator& __a);
1337cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
13380b57cec5SDimitry Andric  promise(const promise& __rhs) = delete;
13390b57cec5SDimitry Andric  ~promise();
13400b57cec5SDimitry Andric
13410b57cec5SDimitry Andric  // assignment
1342cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
13435f757f3fSDimitry Andric    promise(std::move(__rhs)).swap(*this);
13440b57cec5SDimitry Andric    return *this;
13450b57cec5SDimitry Andric  }
13460b57cec5SDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1347e8d8bef9SDimitry Andric
1348cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
13490b57cec5SDimitry Andric
13500b57cec5SDimitry Andric  // retrieving the result
13510b57cec5SDimitry Andric  future<void> get_future();
13520b57cec5SDimitry Andric
13530b57cec5SDimitry Andric  // setting the result
13540b57cec5SDimitry Andric  void set_value();
13550b57cec5SDimitry Andric  void set_exception(exception_ptr __p);
13560b57cec5SDimitry Andric
13570b57cec5SDimitry Andric  // setting the result with deferred notification
13580b57cec5SDimitry Andric  void set_value_at_thread_exit();
13590b57cec5SDimitry Andric  void set_exception_at_thread_exit(exception_ptr __p);
13600b57cec5SDimitry Andric};
13610b57cec5SDimitry Andric
13620b57cec5SDimitry Andrictemplate <class _Alloc>
1363cb14a3feSDimitry Andricpromise<void>::promise(allocator_arg_t, const _Alloc& __a0) {
13640b57cec5SDimitry Andric  typedef __assoc_sub_state_alloc<_Alloc> _State;
13650b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
13660b57cec5SDimitry Andric  typedef __allocator_destructor<_A2> _D2;
13670b57cec5SDimitry Andric  _A2 __a(__a0);
13680b57cec5SDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
13695f757f3fSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
13705f757f3fSDimitry Andric  __state_ = std::addressof(*__hold.release());
13710b57cec5SDimitry Andric}
13720b57cec5SDimitry Andric
13730b57cec5SDimitry Andrictemplate <class _Rp>
1374cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT {
13750b57cec5SDimitry Andric  __x.swap(__y);
13760b57cec5SDimitry Andric}
13770b57cec5SDimitry Andric
13780b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
1379cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc> : public true_type {};
13800b57cec5SDimitry Andric
13810b57cec5SDimitry Andric// packaged_task
13820b57cec5SDimitry Andric
1383cb14a3feSDimitry Andrictemplate <class _Fp>
1384cb14a3feSDimitry Andricclass __packaged_task_base;
13850b57cec5SDimitry Andric
13860b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1387cb14a3feSDimitry Andricclass __packaged_task_base<_Rp(_ArgTypes...)> {
13880b57cec5SDimitry Andric  __packaged_task_base(const __packaged_task_base&);
13890b57cec5SDimitry Andric  __packaged_task_base& operator=(const __packaged_task_base&);
1390cb14a3feSDimitry Andric
13910b57cec5SDimitry Andricpublic:
1392cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_base() {}
1393bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL
13940b57cec5SDimitry Andric  virtual ~__packaged_task_base() {}
13950b57cec5SDimitry Andric  virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
13960b57cec5SDimitry Andric  virtual void destroy()                                  = 0;
13970b57cec5SDimitry Andric  virtual void destroy_deallocate()                       = 0;
13980b57cec5SDimitry Andric  virtual _Rp operator()(_ArgTypes&&...)                  = 0;
13990b57cec5SDimitry Andric};
14000b57cec5SDimitry Andric
1401cb14a3feSDimitry Andrictemplate <class _FD, class _Alloc, class _FB>
1402cb14a3feSDimitry Andricclass __packaged_task_func;
14030b57cec5SDimitry Andric
14040b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1405cb14a3feSDimitry Andricclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __packaged_task_base<_Rp(_ArgTypes...)> {
14060b57cec5SDimitry Andric  __compressed_pair<_Fp, _Alloc> __f_;
1407cb14a3feSDimitry Andric
14080b57cec5SDimitry Andricpublic:
1409cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
1410cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(_Fp&& __f) : __f_(std::move(__f), __default_init_tag()) {}
1411cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {}
1412cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_func(_Fp&& __f, const _Alloc& __a) : __f_(std::move(__f), __a) {}
141306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
141406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy();
141506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate();
141606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __args);
14170b57cec5SDimitry Andric};
14180b57cec5SDimitry Andric
14190b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1420cb14a3feSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1421cb14a3feSDimitry Andric    __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT {
14225f757f3fSDimitry Andric  ::new ((void*)__p) __packaged_task_func(std::move(__f_.first()), std::move(__f_.second()));
14230b57cec5SDimitry Andric}
14240b57cec5SDimitry Andric
14250b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1426cb14a3feSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() {
14270b57cec5SDimitry Andric  __f_.~__compressed_pair<_Fp, _Alloc>();
14280b57cec5SDimitry Andric}
14290b57cec5SDimitry Andric
14300b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1431cb14a3feSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() {
14320b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
14330b57cec5SDimitry Andric  typedef allocator_traits<_Ap> _ATraits;
14340b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
14350b57cec5SDimitry Andric  _Ap __a(__f_.second());
14360b57cec5SDimitry Andric  __f_.~__compressed_pair<_Fp, _Alloc>();
14370b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
14380b57cec5SDimitry Andric}
14390b57cec5SDimitry Andric
14400b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1441cb14a3feSDimitry Andric_Rp __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) {
14425f757f3fSDimitry Andric  return std::__invoke(__f_.first(), std::forward<_ArgTypes>(__arg)...);
14430b57cec5SDimitry Andric}
14440b57cec5SDimitry Andric
1445cb14a3feSDimitry Andrictemplate <class _Callable>
1446cb14a3feSDimitry Andricclass __packaged_task_function;
14470b57cec5SDimitry Andric
14480b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1449cb14a3feSDimitry Andricclass __packaged_task_function<_Rp(_ArgTypes...)> {
14500b57cec5SDimitry Andric  typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1451e8d8bef9SDimitry Andric
1452cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __base* __get_buf() { return (__base*)&__buf_; }
1453e8d8bef9SDimitry Andric
1454bdd1243dSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
14550b57cec5SDimitry Andric  typename aligned_storage<3 * sizeof(void*)>::type __buf_;
1456bdd1243dSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_POP
14570b57cec5SDimitry Andric  __base* __f_;
14580b57cec5SDimitry Andric
14590b57cec5SDimitry Andricpublic:
14600b57cec5SDimitry Andric  typedef _Rp result_type;
14610b57cec5SDimitry Andric
14620b57cec5SDimitry Andric  // construct/copy/destroy:
1463cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
14640b57cec5SDimitry Andric  template <class _Fp>
146506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f);
14660b57cec5SDimitry Andric  template <class _Fp, class _Alloc>
146706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
14680b57cec5SDimitry Andric
146906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
147006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
14710b57cec5SDimitry Andric
14720b57cec5SDimitry Andric  __packaged_task_function(const __packaged_task_function&)            = delete;
14730b57cec5SDimitry Andric  __packaged_task_function& operator=(const __packaged_task_function&) = delete;
14740b57cec5SDimitry Andric
147506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function();
14760b57cec5SDimitry Andric
147706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT;
14780b57cec5SDimitry Andric
1479cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
14800b57cec5SDimitry Andric};
14810b57cec5SDimitry Andric
14820b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1483cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT {
14840b57cec5SDimitry Andric  if (__f.__f_ == nullptr)
14850b57cec5SDimitry Andric    __f_ = nullptr;
1486cb14a3feSDimitry Andric  else if (__f.__f_ == __f.__get_buf()) {
1487e8d8bef9SDimitry Andric    __f.__f_->__move_to(__get_buf());
14880b57cec5SDimitry Andric    __f_ = (__base*)&__buf_;
1489cb14a3feSDimitry Andric  } else {
14900b57cec5SDimitry Andric    __f_     = __f.__f_;
14910b57cec5SDimitry Andric    __f.__f_ = nullptr;
14920b57cec5SDimitry Andric  }
14930b57cec5SDimitry Andric}
14940b57cec5SDimitry Andric
14950b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
14960b57cec5SDimitry Andrictemplate <class _Fp>
1497cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) : __f_(nullptr) {
149806c3fb27SDimitry Andric  typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
14990b57cec5SDimitry Andric  typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1500cb14a3feSDimitry Andric  if (sizeof(_FF) <= sizeof(__buf_)) {
15015f757f3fSDimitry Andric    ::new ((void*)&__buf_) _FF(std::forward<_Fp>(__f));
15020b57cec5SDimitry Andric    __f_ = (__base*)&__buf_;
1503cb14a3feSDimitry Andric  } else {
15040b57cec5SDimitry Andric    typedef allocator<_FF> _Ap;
15050b57cec5SDimitry Andric    _Ap __a;
15060b57cec5SDimitry Andric    typedef __allocator_destructor<_Ap> _Dp;
15070b57cec5SDimitry Andric    unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
15085f757f3fSDimitry Andric    ::new ((void*)__hold.get()) _FF(std::forward<_Fp>(__f), allocator<_FR>(__a));
15090b57cec5SDimitry Andric    __f_ = __hold.release();
15100b57cec5SDimitry Andric  }
15110b57cec5SDimitry Andric}
15120b57cec5SDimitry Andric
15130b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
15140b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc>
1515cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1516cb14a3feSDimitry Andric    : __f_(nullptr) {
151706c3fb27SDimitry Andric  typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
15180b57cec5SDimitry Andric  typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1519cb14a3feSDimitry Andric  if (sizeof(_FF) <= sizeof(__buf_)) {
15200b57cec5SDimitry Andric    __f_ = (__base*)&__buf_;
15215f757f3fSDimitry Andric    ::new ((void*)__f_) _FF(std::forward<_Fp>(__f));
1522cb14a3feSDimitry Andric  } else {
15230b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
15240b57cec5SDimitry Andric    _Ap __a(__a0);
15250b57cec5SDimitry Andric    typedef __allocator_destructor<_Ap> _Dp;
15260b57cec5SDimitry Andric    unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1527cb14a3feSDimitry Andric    ::new ((void*)std::addressof(*__hold.get())) _FF(std::forward<_Fp>(__f), _Alloc(__a));
15285f757f3fSDimitry Andric    __f_ = std::addressof(*__hold.release());
15290b57cec5SDimitry Andric  }
15300b57cec5SDimitry Andric}
15310b57cec5SDimitry Andric
15320b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
15330b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>&
1534cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT {
1535e8d8bef9SDimitry Andric  if (__f_ == __get_buf())
15360b57cec5SDimitry Andric    __f_->destroy();
15370b57cec5SDimitry Andric  else if (__f_)
15380b57cec5SDimitry Andric    __f_->destroy_deallocate();
15390b57cec5SDimitry Andric  __f_ = nullptr;
15400b57cec5SDimitry Andric  if (__f.__f_ == nullptr)
15410b57cec5SDimitry Andric    __f_ = nullptr;
1542cb14a3feSDimitry Andric  else if (__f.__f_ == __f.__get_buf()) {
1543e8d8bef9SDimitry Andric    __f.__f_->__move_to(__get_buf());
1544e8d8bef9SDimitry Andric    __f_ = __get_buf();
1545cb14a3feSDimitry Andric  } else {
15460b57cec5SDimitry Andric    __f_     = __f.__f_;
15470b57cec5SDimitry Andric    __f.__f_ = nullptr;
15480b57cec5SDimitry Andric  }
15490b57cec5SDimitry Andric  return *this;
15500b57cec5SDimitry Andric}
15510b57cec5SDimitry Andric
15520b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1553cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() {
1554e8d8bef9SDimitry Andric  if (__f_ == __get_buf())
15550b57cec5SDimitry Andric    __f_->destroy();
15560b57cec5SDimitry Andric  else if (__f_)
15570b57cec5SDimitry Andric    __f_->destroy_deallocate();
15580b57cec5SDimitry Andric}
15590b57cec5SDimitry Andric
15600b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1561cb14a3feSDimitry Andric_LIBCPP_NO_CFI void __packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT {
1562cb14a3feSDimitry Andric  if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) {
1563bdd1243dSDimitry Andric    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
15640b57cec5SDimitry Andric    typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1565bdd1243dSDimitry Andric    _LIBCPP_SUPPRESS_DEPRECATED_POP
15660b57cec5SDimitry Andric    __base* __t = (__base*)&__tempbuf;
15670b57cec5SDimitry Andric    __f_->__move_to(__t);
15680b57cec5SDimitry Andric    __f_->destroy();
15690b57cec5SDimitry Andric    __f_ = nullptr;
15700b57cec5SDimitry Andric    __f.__f_->__move_to((__base*)&__buf_);
15710b57cec5SDimitry Andric    __f.__f_->destroy();
15720b57cec5SDimitry Andric    __f.__f_ = nullptr;
15730b57cec5SDimitry Andric    __f_     = (__base*)&__buf_;
15740b57cec5SDimitry Andric    __t->__move_to((__base*)&__f.__buf_);
15750b57cec5SDimitry Andric    __t->destroy();
15760b57cec5SDimitry Andric    __f.__f_ = (__base*)&__f.__buf_;
1577cb14a3feSDimitry Andric  } else if (__f_ == (__base*)&__buf_) {
15780b57cec5SDimitry Andric    __f_->__move_to((__base*)&__f.__buf_);
15790b57cec5SDimitry Andric    __f_->destroy();
15800b57cec5SDimitry Andric    __f_     = __f.__f_;
15810b57cec5SDimitry Andric    __f.__f_ = (__base*)&__f.__buf_;
1582cb14a3feSDimitry Andric  } else if (__f.__f_ == (__base*)&__f.__buf_) {
15830b57cec5SDimitry Andric    __f.__f_->__move_to((__base*)&__buf_);
15840b57cec5SDimitry Andric    __f.__f_->destroy();
15850b57cec5SDimitry Andric    __f.__f_ = __f_;
15860b57cec5SDimitry Andric    __f_     = (__base*)&__buf_;
1587cb14a3feSDimitry Andric  } else
15885f757f3fSDimitry Andric    std::swap(__f_, __f.__f_);
15890b57cec5SDimitry Andric}
15900b57cec5SDimitry Andric
15910b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1592cb14a3feSDimitry Andricinline _Rp __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const {
15935f757f3fSDimitry Andric  return (*__f_)(std::forward<_ArgTypes>(__arg)...);
15940b57cec5SDimitry Andric}
15950b57cec5SDimitry Andric
15960b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1597cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<_Rp(_ArgTypes...)> {
15980b57cec5SDimitry Andricpublic:
15990b57cec5SDimitry Andric  typedef _Rp result_type; // extension
16000b57cec5SDimitry Andric
16010b57cec5SDimitry Andricprivate:
16020b57cec5SDimitry Andric  __packaged_task_function<result_type(_ArgTypes...)> __f_;
16030b57cec5SDimitry Andric  promise<result_type> __p_;
16040b57cec5SDimitry Andric
16050b57cec5SDimitry Andricpublic:
16060b57cec5SDimitry Andric  // construction and destruction
1607cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}
1608cb14a3feSDimitry Andric  template <class _Fp, class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
1609cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
1610cb14a3feSDimitry Andric  template <class _Fp, class _Allocator, class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
1611cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1612cb14a3feSDimitry Andric      : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
16130b57cec5SDimitry Andric  // ~packaged_task() = default;
16140b57cec5SDimitry Andric
16150b57cec5SDimitry Andric  // no copy
16160b57cec5SDimitry Andric  packaged_task(const packaged_task&)            = delete;
16170b57cec5SDimitry Andric  packaged_task& operator=(const packaged_task&) = delete;
16180b57cec5SDimitry Andric
16190b57cec5SDimitry Andric  // move support
1620cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT
1621cb14a3feSDimitry Andric      : __f_(std::move(__other.__f_)),
1622cb14a3feSDimitry Andric        __p_(std::move(__other.__p_)) {}
1623cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT {
16245f757f3fSDimitry Andric    __f_ = std::move(__other.__f_);
16255f757f3fSDimitry Andric    __p_ = std::move(__other.__p_);
16260b57cec5SDimitry Andric    return *this;
16270b57cec5SDimitry Andric  }
1628cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT {
16290b57cec5SDimitry Andric    __f_.swap(__other.__f_);
16300b57cec5SDimitry Andric    __p_.swap(__other.__p_);
16310b57cec5SDimitry Andric  }
16320b57cec5SDimitry Andric
1633cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
16340b57cec5SDimitry Andric
16350b57cec5SDimitry Andric  // result retrieval
1636cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); }
16370b57cec5SDimitry Andric
16380b57cec5SDimitry Andric  // execution
163906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
164006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
16410b57cec5SDimitry Andric
164206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reset();
16430b57cec5SDimitry Andric};
16440b57cec5SDimitry Andric
16450b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1646cb14a3feSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) {
16470b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
16480b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
16490b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
16500b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
165106c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1652cb14a3feSDimitry Andric  try {
165306c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16545f757f3fSDimitry Andric    __p_.set_value(__f_(std::forward<_ArgTypes>(__args)...));
165506c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1656cb14a3feSDimitry Andric  } catch (...) {
16570b57cec5SDimitry Andric    __p_.set_exception(current_exception());
16580b57cec5SDimitry Andric  }
165906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16600b57cec5SDimitry Andric}
16610b57cec5SDimitry Andric
16620b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1663cb14a3feSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {
16640b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
16650b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
16660b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
16670b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
166806c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1669cb14a3feSDimitry Andric  try {
167006c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16715f757f3fSDimitry Andric    __p_.set_value_at_thread_exit(__f_(std::forward<_ArgTypes>(__args)...));
167206c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1673cb14a3feSDimitry Andric  } catch (...) {
16740b57cec5SDimitry Andric    __p_.set_exception_at_thread_exit(current_exception());
16750b57cec5SDimitry Andric  }
167606c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16770b57cec5SDimitry Andric}
16780b57cec5SDimitry Andric
16790b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1680cb14a3feSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::reset() {
16810b57cec5SDimitry Andric  if (!valid())
16820b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
16830b57cec5SDimitry Andric  __p_ = promise<result_type>();
16840b57cec5SDimitry Andric}
16850b57cec5SDimitry Andric
16860b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1687cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<void(_ArgTypes...)> {
16880b57cec5SDimitry Andricpublic:
16890b57cec5SDimitry Andric  typedef void result_type; // extension
16900b57cec5SDimitry Andric
16910b57cec5SDimitry Andricprivate:
16920b57cec5SDimitry Andric  __packaged_task_function<result_type(_ArgTypes...)> __f_;
16930b57cec5SDimitry Andric  promise<result_type> __p_;
16940b57cec5SDimitry Andric
16950b57cec5SDimitry Andricpublic:
16960b57cec5SDimitry Andric  // construction and destruction
1697cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}
1698cb14a3feSDimitry Andric  template <class _Fp, class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
1699cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
1700cb14a3feSDimitry Andric  template <class _Fp, class _Allocator, class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
1701cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1702cb14a3feSDimitry Andric      : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
17030b57cec5SDimitry Andric  // ~packaged_task() = default;
17040b57cec5SDimitry Andric
17050b57cec5SDimitry Andric  // no copy
17060b57cec5SDimitry Andric  packaged_task(const packaged_task&)            = delete;
17070b57cec5SDimitry Andric  packaged_task& operator=(const packaged_task&) = delete;
17080b57cec5SDimitry Andric
17090b57cec5SDimitry Andric  // move support
1710cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT
1711cb14a3feSDimitry Andric      : __f_(std::move(__other.__f_)),
1712cb14a3feSDimitry Andric        __p_(std::move(__other.__p_)) {}
1713cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT {
17145f757f3fSDimitry Andric    __f_ = std::move(__other.__f_);
17155f757f3fSDimitry Andric    __p_ = std::move(__other.__p_);
17160b57cec5SDimitry Andric    return *this;
17170b57cec5SDimitry Andric  }
1718cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT {
17190b57cec5SDimitry Andric    __f_.swap(__other.__f_);
17200b57cec5SDimitry Andric    __p_.swap(__other.__p_);
17210b57cec5SDimitry Andric  }
17220b57cec5SDimitry Andric
1723cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
17240b57cec5SDimitry Andric
17250b57cec5SDimitry Andric  // result retrieval
1726cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); }
17270b57cec5SDimitry Andric
17280b57cec5SDimitry Andric  // execution
172906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
173006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
17310b57cec5SDimitry Andric
173206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reset();
17330b57cec5SDimitry Andric};
17340b57cec5SDimitry Andric
1735bdd1243dSDimitry Andric#if _LIBCPP_STD_VER >= 17
1736bdd1243dSDimitry Andric
1737bdd1243dSDimitry Andrictemplate <class _Rp, class... _Args>
1738bdd1243dSDimitry Andricpackaged_task(_Rp (*)(_Args...)) -> packaged_task<_Rp(_Args...)>;
1739bdd1243dSDimitry Andric
1740bdd1243dSDimitry Andrictemplate <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
1741bdd1243dSDimitry Andricpackaged_task(_Fp) -> packaged_task<_Stripped>;
1742bdd1243dSDimitry Andric
1743bdd1243dSDimitry Andric#endif
1744bdd1243dSDimitry Andric
17450b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1746cb14a3feSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) {
17470b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
17480b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
17490b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
17500b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
175106c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1752cb14a3feSDimitry Andric  try {
175306c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17545f757f3fSDimitry Andric    __f_(std::forward<_ArgTypes>(__args)...);
17550b57cec5SDimitry Andric    __p_.set_value();
175606c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1757cb14a3feSDimitry Andric  } catch (...) {
17580b57cec5SDimitry Andric    __p_.set_exception(current_exception());
17590b57cec5SDimitry Andric  }
176006c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17610b57cec5SDimitry Andric}
17620b57cec5SDimitry Andric
17630b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1764cb14a3feSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {
17650b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
17660b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
17670b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
17680b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
176906c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1770cb14a3feSDimitry Andric  try {
177106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17725f757f3fSDimitry Andric    __f_(std::forward<_ArgTypes>(__args)...);
17730b57cec5SDimitry Andric    __p_.set_value_at_thread_exit();
177406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1775cb14a3feSDimitry Andric  } catch (...) {
17760b57cec5SDimitry Andric    __p_.set_exception_at_thread_exit(current_exception());
17770b57cec5SDimitry Andric  }
177806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17790b57cec5SDimitry Andric}
17800b57cec5SDimitry Andric
17810b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1782cb14a3feSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::reset() {
17830b57cec5SDimitry Andric  if (!valid())
17840b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
17850b57cec5SDimitry Andric  __p_ = promise<result_type>();
17860b57cec5SDimitry Andric}
17870b57cec5SDimitry Andric
1788fe6060f1SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1789cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
1790cb14a3feSDimitry Andricswap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT {
17910b57cec5SDimitry Andric  __x.swap(__y);
17920b57cec5SDimitry Andric}
17930b57cec5SDimitry Andric
17940b57cec5SDimitry Andrictemplate <class _Callable, class _Alloc>
1795cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {};
17960b57cec5SDimitry Andric
17970b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1798cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f) {
1799cb14a3feSDimitry Andric  unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
1800cb14a3feSDimitry Andric      new __deferred_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
18010b57cec5SDimitry Andric  return future<_Rp>(__h.get());
18020b57cec5SDimitry Andric}
18030b57cec5SDimitry Andric
18040b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1805cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f) {
1806cb14a3feSDimitry Andric  unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
1807cb14a3feSDimitry Andric      new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
18085f757f3fSDimitry Andric  std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
18090b57cec5SDimitry Andric  return future<_Rp>(__h.get());
18100b57cec5SDimitry Andric}
18110b57cec5SDimitry Andric
1812e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1813e8d8bef9SDimitry Andric
18140b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
1815cb14a3feSDimitry Andricclass _LIBCPP_HIDDEN __async_func {
18160b57cec5SDimitry Andric  tuple<_Fp, _Args...> __f_;
18170b57cec5SDimitry Andric
18180b57cec5SDimitry Andricpublic:
18190b57cec5SDimitry Andric  typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
18200b57cec5SDimitry Andric
1821cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_func(_Fp&& __f, _Args&&... __args)
18225f757f3fSDimitry Andric      : __f_(std::move(__f), std::move(__args)...) {}
18230b57cec5SDimitry Andric
1824cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __async_func(__async_func&& __f) : __f_(std::move(__f.__f_)) {}
18250b57cec5SDimitry Andric
1826cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp operator()() {
18270b57cec5SDimitry Andric    typedef typename __make_tuple_indices<1 + sizeof...(_Args), 1>::type _Index;
18280b57cec5SDimitry Andric    return __execute(_Index());
18290b57cec5SDimitry Andric  }
1830cb14a3feSDimitry Andric
18310b57cec5SDimitry Andricprivate:
18320b57cec5SDimitry Andric  template <size_t... _Indices>
1833cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp __execute(__tuple_indices<_Indices...>) {
18345f757f3fSDimitry Andric    return std::__invoke(std::move(std::get<0>(__f_)), std::move(std::get<_Indices>(__f_))...);
18350b57cec5SDimitry Andric  }
18360b57cec5SDimitry Andric};
18370b57cec5SDimitry Andric
1838cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool __does_policy_contain(launch __policy, launch __value) {
1839cb14a3feSDimitry Andric  return (int(__policy) & int(__value)) != 0;
1840cb14a3feSDimitry Andric}
18410b57cec5SDimitry Andric
18420b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
1843bdd1243dSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
184406c3fb27SDimitry Andric    future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
1845cb14a3feSDimitry Andric    async(launch __policy, _Fp&& __f, _Args&&... __args) {
184606c3fb27SDimitry Andric  typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF;
18470b57cec5SDimitry Andric  typedef typename _BF::_Rp _Rp;
18480b57cec5SDimitry Andric
184906c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1850cb14a3feSDimitry Andric  try {
18510b57cec5SDimitry Andric#  endif
18520b57cec5SDimitry Andric    if (__does_policy_contain(__policy, launch::async))
1853cb14a3feSDimitry Andric      return std::__make_async_assoc_state<_Rp>(
1854cb14a3feSDimitry Andric          _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...));
185506c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1856cb14a3feSDimitry Andric  } catch (...) {
1857cb14a3feSDimitry Andric    if (__policy == launch::async)
1858cb14a3feSDimitry Andric      throw;
18590b57cec5SDimitry Andric  }
18600b57cec5SDimitry Andric#  endif
18610b57cec5SDimitry Andric
18620b57cec5SDimitry Andric  if (__does_policy_contain(__policy, launch::deferred))
1863cb14a3feSDimitry Andric    return std::__make_deferred_assoc_state<_Rp>(
1864cb14a3feSDimitry Andric        _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...));
18650b57cec5SDimitry Andric  return future<_Rp>{};
18660b57cec5SDimitry Andric}
18670b57cec5SDimitry Andric
18680b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
18695f757f3fSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
187006c3fb27SDimitry Andric    future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
1871cb14a3feSDimitry Andric    async(_Fp&& __f, _Args&&... __args) {
1872cb14a3feSDimitry Andric  return std::async(launch::any, std::forward<_Fp>(__f), std::forward<_Args>(__args)...);
18730b57cec5SDimitry Andric}
18740b57cec5SDimitry Andric
1875e8d8bef9SDimitry Andric#endif // C++03
18760b57cec5SDimitry Andric
18770b57cec5SDimitry Andric// shared_future
18780b57cec5SDimitry Andric
18790b57cec5SDimitry Andrictemplate <class _Rp>
1880cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future {
18810b57cec5SDimitry Andric  __assoc_state<_Rp>* __state_;
18820b57cec5SDimitry Andric
18830b57cec5SDimitry Andricpublic:
1884cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1885cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1886cb14a3feSDimitry Andric    if (__state_)
1887cb14a3feSDimitry Andric      __state_->__add_shared();
1888cb14a3feSDimitry Andric  }
1889cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1890cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1891cb14a3feSDimitry Andric    __rhs.__state_ = nullptr;
1892cb14a3feSDimitry Andric  }
189306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~shared_future();
189406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
1895cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT {
18965f757f3fSDimitry Andric    shared_future(std::move(__rhs)).swap(*this);
18970b57cec5SDimitry Andric    return *this;
18980b57cec5SDimitry Andric  }
18990b57cec5SDimitry Andric
19000b57cec5SDimitry Andric  // retrieving the value
1901cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const _Rp& get() const { return __state_->copy(); }
19020b57cec5SDimitry Andric
1903cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
19040b57cec5SDimitry Andric
19050b57cec5SDimitry Andric  // functions to check state
1906cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
19070b57cec5SDimitry Andric
1908cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
19090b57cec5SDimitry Andric  template <class _Rep, class _Period>
1910cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1911cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1912cb14a3feSDimitry Andric  }
19130b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1914cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1915cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1916cb14a3feSDimitry Andric  }
19170b57cec5SDimitry Andric};
19180b57cec5SDimitry Andric
19190b57cec5SDimitry Andrictemplate <class _Rp>
1920cb14a3feSDimitry Andricshared_future<_Rp>::~shared_future() {
19210b57cec5SDimitry Andric  if (__state_)
19220b57cec5SDimitry Andric    __state_->__release_shared();
19230b57cec5SDimitry Andric}
19240b57cec5SDimitry Andric
19250b57cec5SDimitry Andrictemplate <class _Rp>
1926cb14a3feSDimitry Andricshared_future<_Rp>& shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT {
19270b57cec5SDimitry Andric  if (__rhs.__state_)
19280b57cec5SDimitry Andric    __rhs.__state_->__add_shared();
19290b57cec5SDimitry Andric  if (__state_)
19300b57cec5SDimitry Andric    __state_->__release_shared();
19310b57cec5SDimitry Andric  __state_ = __rhs.__state_;
19320b57cec5SDimitry Andric  return *this;
19330b57cec5SDimitry Andric}
19340b57cec5SDimitry Andric
19350b57cec5SDimitry Andrictemplate <class _Rp>
1936cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&> {
19370b57cec5SDimitry Andric  __assoc_state<_Rp&>* __state_;
19380b57cec5SDimitry Andric
19390b57cec5SDimitry Andricpublic:
1940cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1941cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {
1942cb14a3feSDimitry Andric    if (__state_)
1943cb14a3feSDimitry Andric      __state_->__add_shared();
1944cb14a3feSDimitry Andric  }
1945cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1946cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1947cb14a3feSDimitry Andric    __rhs.__state_ = nullptr;
1948cb14a3feSDimitry Andric  }
194906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~shared_future();
195006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs);
1951cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT {
19525f757f3fSDimitry Andric    shared_future(std::move(__rhs)).swap(*this);
19530b57cec5SDimitry Andric    return *this;
19540b57cec5SDimitry Andric  }
19550b57cec5SDimitry Andric
19560b57cec5SDimitry Andric  // retrieving the value
1957cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& get() const { return __state_->copy(); }
19580b57cec5SDimitry Andric
1959cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
19600b57cec5SDimitry Andric
19610b57cec5SDimitry Andric  // functions to check state
1962cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
19630b57cec5SDimitry Andric
1964cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
19650b57cec5SDimitry Andric  template <class _Rep, class _Period>
1966cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1967cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1968cb14a3feSDimitry Andric  }
19690b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1970cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1971cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1972cb14a3feSDimitry Andric  }
19730b57cec5SDimitry Andric};
19740b57cec5SDimitry Andric
19750b57cec5SDimitry Andrictemplate <class _Rp>
1976cb14a3feSDimitry Andricshared_future<_Rp&>::~shared_future() {
19770b57cec5SDimitry Andric  if (__state_)
19780b57cec5SDimitry Andric    __state_->__release_shared();
19790b57cec5SDimitry Andric}
19800b57cec5SDimitry Andric
19810b57cec5SDimitry Andrictemplate <class _Rp>
1982cb14a3feSDimitry Andricshared_future<_Rp&>& shared_future<_Rp&>::operator=(const shared_future& __rhs) {
19830b57cec5SDimitry Andric  if (__rhs.__state_)
19840b57cec5SDimitry Andric    __rhs.__state_->__add_shared();
19850b57cec5SDimitry Andric  if (__state_)
19860b57cec5SDimitry Andric    __state_->__release_shared();
19870b57cec5SDimitry Andric  __state_ = __rhs.__state_;
19880b57cec5SDimitry Andric  return *this;
19890b57cec5SDimitry Andric}
19900b57cec5SDimitry Andric
19910b57cec5SDimitry Andrictemplate <>
1992cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI shared_future<void> {
19930b57cec5SDimitry Andric  __assoc_sub_state* __state_;
19940b57cec5SDimitry Andric
19950b57cec5SDimitry Andricpublic:
1996cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1997cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {
1998cb14a3feSDimitry Andric    if (__state_)
1999cb14a3feSDimitry Andric      __state_->__add_shared();
2000cb14a3feSDimitry Andric  }
2001cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
2002cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
2003cb14a3feSDimitry Andric    __rhs.__state_ = nullptr;
2004cb14a3feSDimitry Andric  }
20050b57cec5SDimitry Andric  ~shared_future();
20060b57cec5SDimitry Andric  shared_future& operator=(const shared_future& __rhs);
2007cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT {
20085f757f3fSDimitry Andric    shared_future(std::move(__rhs)).swap(*this);
20090b57cec5SDimitry Andric    return *this;
20100b57cec5SDimitry Andric  }
20110b57cec5SDimitry Andric
20120b57cec5SDimitry Andric  // retrieving the value
2013cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void get() const { __state_->copy(); }
20140b57cec5SDimitry Andric
2015cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
20160b57cec5SDimitry Andric
20170b57cec5SDimitry Andric  // functions to check state
2018cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
20190b57cec5SDimitry Andric
2020cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
20210b57cec5SDimitry Andric  template <class _Rep, class _Period>
2022cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
2023cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
2024cb14a3feSDimitry Andric  }
20250b57cec5SDimitry Andric  template <class _Clock, class _Duration>
2026cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
2027cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
2028cb14a3feSDimitry Andric  }
20290b57cec5SDimitry Andric};
20300b57cec5SDimitry Andric
20310b57cec5SDimitry Andrictemplate <class _Rp>
2032cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT {
20330b57cec5SDimitry Andric  __x.swap(__y);
20340b57cec5SDimitry Andric}
20350b57cec5SDimitry Andric
20360b57cec5SDimitry Andrictemplate <class _Rp>
2037cb14a3feSDimitry Andricinline shared_future<_Rp> future<_Rp>::share() _NOEXCEPT {
20385f757f3fSDimitry Andric  return shared_future<_Rp>(std::move(*this));
20390b57cec5SDimitry Andric}
20400b57cec5SDimitry Andric
20410b57cec5SDimitry Andrictemplate <class _Rp>
2042cb14a3feSDimitry Andricinline shared_future<_Rp&> future<_Rp&>::share() _NOEXCEPT {
20435f757f3fSDimitry Andric  return shared_future<_Rp&>(std::move(*this));
20440b57cec5SDimitry Andric}
20450b57cec5SDimitry Andric
2046cb14a3feSDimitry Andricinline shared_future<void> future<void>::share() _NOEXCEPT { return shared_future<void>(std::move(*this)); }
20470b57cec5SDimitry Andric
20480b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
20490b57cec5SDimitry Andric
2050b3edf446SDimitry Andric_LIBCPP_POP_MACROS
2051b3edf446SDimitry Andric
2052bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
2053bdd1243dSDimitry Andric#  include <chrono>
2054bdd1243dSDimitry Andric#endif
2055bdd1243dSDimitry Andric
205606c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
205706c3fb27SDimitry Andric#  include <atomic>
205806c3fb27SDimitry Andric#  include <cstdlib>
205906c3fb27SDimitry Andric#  include <exception>
20605f757f3fSDimitry Andric#  include <iosfwd>
206106c3fb27SDimitry Andric#  include <system_error>
206206c3fb27SDimitry Andric#endif
206306c3fb27SDimitry Andric
20640b57cec5SDimitry Andric#endif // _LIBCPP_FUTURE
2065