xref: /freebsd/contrib/llvm-project/libcxx/include/future (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
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
36581ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
366e8d8bef9SDimitry Andric#include <__availability>
36781ad6265SDimitry Andric#include <__chrono/duration.h>
36881ad6265SDimitry Andric#include <__chrono/time_point.h>
369fe6060f1SDimitry Andric#include <__config>
37006c3fb27SDimitry Andric#include <__exception/exception_ptr.h>
37106c3fb27SDimitry Andric#include <__memory/addressof.h>
37206c3fb27SDimitry Andric#include <__memory/allocator.h>
373fe6060f1SDimitry Andric#include <__memory/allocator_arg_t.h>
374bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h>
37506c3fb27SDimitry Andric#include <__memory/allocator_traits.h>
37606c3fb27SDimitry Andric#include <__memory/compressed_pair.h>
37706c3fb27SDimitry Andric#include <__memory/pointer_traits.h>
37806c3fb27SDimitry Andric#include <__memory/shared_ptr.h>
37906c3fb27SDimitry Andric#include <__memory/unique_ptr.h>
380fe6060f1SDimitry Andric#include <__memory/uses_allocator.h>
38106c3fb27SDimitry Andric#include <__system_error/error_category.h>
38206c3fb27SDimitry Andric#include <__system_error/error_code.h>
38306c3fb27SDimitry Andric#include <__system_error/error_condition.h>
38406c3fb27SDimitry Andric#include <__type_traits/aligned_storage.h>
385bdd1243dSDimitry Andric#include <__type_traits/strip_signature.h>
3860eae32dcSDimitry Andric#include <__utility/auto_cast.h>
387fe6060f1SDimitry Andric#include <__utility/forward.h>
38881ad6265SDimitry Andric#include <__utility/move.h>
3890b57cec5SDimitry Andric#include <mutex>
390bdd1243dSDimitry Andric#include <new>
39106c3fb27SDimitry Andric#include <stdexcept>
3920b57cec5SDimitry Andric#include <thread>
39304eeddc0SDimitry Andric#include <version>
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3960b57cec5SDimitry Andric#  pragma GCC system_header
3970b57cec5SDimitry Andric#endif
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
40081ad6265SDimitry Andric#  error "<future> is not supported since libc++ has been configured without support for threads."
40181ad6265SDimitry Andric#endif
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric// enum class future_errc
406*cb14a3feSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_errc){
407*cb14a3feSDimitry Andric    future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise};
4080b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
4090b57cec5SDimitry Andric
4100b57cec5SDimitry Andrictemplate <>
4110b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
4120b57cec5SDimitry Andric
41381ad6265SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
4140b57cec5SDimitry Andrictemplate <>
4150b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type {};
4160b57cec5SDimitry Andric#endif
4170b57cec5SDimitry Andric
4180b57cec5SDimitry Andric// enum class launch
419*cb14a3feSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(launch){async = 1, deferred = 2, any = async | deferred};
4200b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
4210b57cec5SDimitry Andric
42281ad6265SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
4230b57cec5SDimitry Andric
4240b57cec5SDimitry Andrictypedef underlying_type<launch>::type __launch_underlying_type;
4250b57cec5SDimitry Andric
426*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR launch operator&(launch __x, launch __y) {
427*cb14a3feSDimitry Andric  return static_cast<launch>(static_cast<__launch_underlying_type>(__x) & static_cast<__launch_underlying_type>(__y));
4280b57cec5SDimitry Andric}
4290b57cec5SDimitry Andric
430*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR launch operator|(launch __x, launch __y) {
431*cb14a3feSDimitry Andric  return static_cast<launch>(static_cast<__launch_underlying_type>(__x) | static_cast<__launch_underlying_type>(__y));
4320b57cec5SDimitry Andric}
4330b57cec5SDimitry Andric
434*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR launch operator^(launch __x, launch __y) {
435*cb14a3feSDimitry Andric  return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^ static_cast<__launch_underlying_type>(__y));
4360b57cec5SDimitry Andric}
4370b57cec5SDimitry Andric
438*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR launch operator~(launch __x) {
4390b57cec5SDimitry Andric  return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
4400b57cec5SDimitry Andric}
4410b57cec5SDimitry Andric
442*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI launch& operator&=(launch& __x, launch __y) {
443*cb14a3feSDimitry Andric  __x = __x & __y;
444*cb14a3feSDimitry Andric  return __x;
4450b57cec5SDimitry Andric}
4460b57cec5SDimitry Andric
447*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI launch& operator|=(launch& __x, launch __y) {
448*cb14a3feSDimitry Andric  __x = __x | __y;
449*cb14a3feSDimitry Andric  return __x;
4500b57cec5SDimitry Andric}
4510b57cec5SDimitry Andric
452*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI launch& operator^=(launch& __x, launch __y) {
453*cb14a3feSDimitry Andric  __x = __x ^ __y;
454*cb14a3feSDimitry Andric  return __x;
4550b57cec5SDimitry Andric}
4560b57cec5SDimitry Andric
45781ad6265SDimitry Andric#endif // !_LIBCPP_CXX03_LANG
4580b57cec5SDimitry Andric
4590b57cec5SDimitry Andric// enum class future_status
460*cb14a3feSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_status){ready, timeout, deferred};
4610b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
4620b57cec5SDimitry Andric
46306c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;
4640b57cec5SDimitry Andric
465*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(future_errc __e) _NOEXCEPT {
4660b57cec5SDimitry Andric  return error_code(static_cast<int>(__e), future_category());
4670b57cec5SDimitry Andric}
4680b57cec5SDimitry Andric
469*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(future_errc __e) _NOEXCEPT {
4700b57cec5SDimitry Andric  return error_condition(static_cast<int>(__e), future_category());
4710b57cec5SDimitry Andric}
4720b57cec5SDimitry Andric
4735f757f3fSDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_future_error(future_errc __ev);
474fe6060f1SDimitry Andric
4755f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future_error : public logic_error {
4765f757f3fSDimitry Andric  error_code __ec_;
4775f757f3fSDimitry Andric
4785f757f3fSDimitry Andric  future_error(error_code);
4795f757f3fSDimitry Andric  friend void __throw_future_error(future_errc);
480*cb14a3feSDimitry Andric  template <class>
481*cb14a3feSDimitry Andric  friend class promise;
4825f757f3fSDimitry Andric
4835f757f3fSDimitry Andricpublic:
4845f757f3fSDimitry Andric#if _LIBCPP_STD_VER >= 17
4855f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit future_error(future_errc __ec) : future_error(std::make_error_code(__ec)) {}
4865f757f3fSDimitry Andric#endif
4875f757f3fSDimitry Andric
488*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
4890b57cec5SDimitry Andric
49006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default;
491bdd1243dSDimitry Andric  ~future_error() _NOEXCEPT override;
4920b57cec5SDimitry Andric};
4930b57cec5SDimitry Andric
4945f757f3fSDimitry Andric// Declared above std::future_error
495*cb14a3feSDimitry Andricvoid __throw_future_error(future_errc __ev) {
49606c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
497753f127fSDimitry Andric  throw future_error(make_error_code(__ev));
4980b57cec5SDimitry Andric#else
49906c3fb27SDimitry Andric  (void)__ev;
50006c3fb27SDimitry Andric  _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode");
5010b57cec5SDimitry Andric#endif
5020b57cec5SDimitry Andric}
5030b57cec5SDimitry Andric
5045f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI __assoc_sub_state : public __shared_count {
5050b57cec5SDimitry Andricprotected:
5060b57cec5SDimitry Andric  exception_ptr __exception_;
5070b57cec5SDimitry Andric  mutable mutex __mut_;
5080b57cec5SDimitry Andric  mutable condition_variable __cv_;
5090b57cec5SDimitry Andric  unsigned __state_;
5100b57cec5SDimitry Andric
511bdd1243dSDimitry Andric  void __on_zero_shared() _NOEXCEPT override;
5120b57cec5SDimitry Andric  void __sub_wait(unique_lock<mutex>& __lk);
513*cb14a3feSDimitry Andric
5140b57cec5SDimitry Andricpublic:
515*cb14a3feSDimitry Andric  enum { __constructed = 1, __future_attached = 2, ready = 4, deferred = 8 };
5160b57cec5SDimitry Andric
517*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __assoc_sub_state() : __state_(0) {}
5180b57cec5SDimitry Andric
519*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool __has_value() const { return (__state_ & __constructed) || (__exception_ != nullptr); }
5200b57cec5SDimitry Andric
521*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __attach_future() {
5220b57cec5SDimitry Andric    lock_guard<mutex> __lk(__mut_);
5230b57cec5SDimitry Andric    bool __has_future_attached = (__state_ & __future_attached) != 0;
5240b57cec5SDimitry Andric    if (__has_future_attached)
5250b57cec5SDimitry Andric      __throw_future_error(future_errc::future_already_retrieved);
5260b57cec5SDimitry Andric    this->__add_shared();
5270b57cec5SDimitry Andric    __state_ |= __future_attached;
5280b57cec5SDimitry Andric  }
5290b57cec5SDimitry Andric
530*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __set_deferred() { __state_ |= deferred; }
5310b57cec5SDimitry Andric
5320b57cec5SDimitry Andric  void __make_ready();
533*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool __is_ready() const { return (__state_ & ready) != 0; }
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric  void set_value();
5360b57cec5SDimitry Andric  void set_value_at_thread_exit();
5370b57cec5SDimitry Andric
5380b57cec5SDimitry Andric  void set_exception(exception_ptr __p);
5390b57cec5SDimitry Andric  void set_exception_at_thread_exit(exception_ptr __p);
5400b57cec5SDimitry Andric
5410b57cec5SDimitry Andric  void copy();
5420b57cec5SDimitry Andric
5430b57cec5SDimitry Andric  void wait();
5440b57cec5SDimitry Andric  template <class _Rep, class _Period>
545*cb14a3feSDimitry Andric  future_status _LIBCPP_HIDE_FROM_ABI wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
5460b57cec5SDimitry Andric  template <class _Clock, class _Duration>
547*cb14a3feSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS future_status
5480b57cec5SDimitry Andric  wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric  virtual void __execute();
5510b57cec5SDimitry Andric};
5520b57cec5SDimitry Andric
5530b57cec5SDimitry Andrictemplate <class _Clock, class _Duration>
554*cb14a3feSDimitry Andricfuture_status __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
5550b57cec5SDimitry Andric  unique_lock<mutex> __lk(__mut_);
5560b57cec5SDimitry Andric  if (__state_ & deferred)
5570b57cec5SDimitry Andric    return future_status::deferred;
5580b57cec5SDimitry Andric  while (!(__state_ & ready) && _Clock::now() < __abs_time)
5590b57cec5SDimitry Andric    __cv_.wait_until(__lk, __abs_time);
5600b57cec5SDimitry Andric  if (__state_ & ready)
5610b57cec5SDimitry Andric    return future_status::ready;
5620b57cec5SDimitry Andric  return future_status::timeout;
5630b57cec5SDimitry Andric}
5640b57cec5SDimitry Andric
5650b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
566*cb14a3feSDimitry Andricinline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
5670b57cec5SDimitry Andric  return wait_until(chrono::steady_clock::now() + __rel_time);
5680b57cec5SDimitry Andric}
5690b57cec5SDimitry Andric
5700b57cec5SDimitry Andrictemplate <class _Rp>
571*cb14a3feSDimitry Andricclass _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state {
5720b57cec5SDimitry Andric  typedef __assoc_sub_state base;
573bdd1243dSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
5745f757f3fSDimitry Andric  typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up;
575bdd1243dSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_POP
576*cb14a3feSDimitry Andric
5770b57cec5SDimitry Andricprotected:
5780b57cec5SDimitry Andric  _Up __value_;
5790b57cec5SDimitry Andric
58006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
5810b57cec5SDimitry Andric
582*cb14a3feSDimitry Andricpublic:
5830b57cec5SDimitry Andric  template <class _Arg>
58406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg);
5850b57cec5SDimitry Andric
5860b57cec5SDimitry Andric  template <class _Arg>
58706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg);
5880b57cec5SDimitry Andric
58906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp move();
59006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy();
5910b57cec5SDimitry Andric};
5920b57cec5SDimitry Andric
5930b57cec5SDimitry Andrictemplate <class _Rp>
594*cb14a3feSDimitry Andricvoid __assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT {
5950b57cec5SDimitry Andric  if (this->__state_ & base::__constructed)
5960b57cec5SDimitry Andric    reinterpret_cast<_Rp*>(&__value_)->~_Rp();
5970b57cec5SDimitry Andric  delete this;
5980b57cec5SDimitry Andric}
5990b57cec5SDimitry Andric
6000b57cec5SDimitry Andrictemplate <class _Rp>
6010b57cec5SDimitry Andrictemplate <class _Arg>
602*cb14a3feSDimitry Andricvoid __assoc_state<_Rp>::set_value(_Arg&& __arg) {
6030b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6040b57cec5SDimitry Andric  if (this->__has_value())
6050b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6065f757f3fSDimitry Andric  ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
6070b57cec5SDimitry Andric  this->__state_ |= base::__constructed | base::ready;
6080b57cec5SDimitry Andric  __cv_.notify_all();
6090b57cec5SDimitry Andric}
6100b57cec5SDimitry Andric
6110b57cec5SDimitry Andrictemplate <class _Rp>
6120b57cec5SDimitry Andrictemplate <class _Arg>
613*cb14a3feSDimitry Andricvoid __assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) {
6140b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6150b57cec5SDimitry Andric  if (this->__has_value())
6160b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6175f757f3fSDimitry Andric  ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
6180b57cec5SDimitry Andric  this->__state_ |= base::__constructed;
6190b57cec5SDimitry Andric  __thread_local_data()->__make_ready_at_thread_exit(this);
6200b57cec5SDimitry Andric}
6210b57cec5SDimitry Andric
6220b57cec5SDimitry Andrictemplate <class _Rp>
623*cb14a3feSDimitry Andric_Rp __assoc_state<_Rp>::move() {
6240b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6250b57cec5SDimitry Andric  this->__sub_wait(__lk);
6260b57cec5SDimitry Andric  if (this->__exception_ != nullptr)
627bdd1243dSDimitry Andric    std::rethrow_exception(this->__exception_);
6285f757f3fSDimitry Andric  return std::move(*reinterpret_cast<_Rp*>(&__value_));
6290b57cec5SDimitry Andric}
6300b57cec5SDimitry Andric
6310b57cec5SDimitry Andrictemplate <class _Rp>
632*cb14a3feSDimitry Andric__add_lvalue_reference_t<_Rp> __assoc_state<_Rp>::copy() {
6330b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6340b57cec5SDimitry Andric  this->__sub_wait(__lk);
6350b57cec5SDimitry Andric  if (this->__exception_ != nullptr)
636bdd1243dSDimitry Andric    std::rethrow_exception(this->__exception_);
6370b57cec5SDimitry Andric  return *reinterpret_cast<_Rp*>(&__value_);
6380b57cec5SDimitry Andric}
6390b57cec5SDimitry Andric
6400b57cec5SDimitry Andrictemplate <class _Rp>
641*cb14a3feSDimitry Andricclass __assoc_state<_Rp&> : public __assoc_sub_state {
6420b57cec5SDimitry Andric  typedef __assoc_sub_state base;
6430b57cec5SDimitry Andric  typedef _Rp* _Up;
644*cb14a3feSDimitry Andric
6450b57cec5SDimitry Andricprotected:
6460b57cec5SDimitry Andric  _Up __value_;
6470b57cec5SDimitry Andric
64806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
6490b57cec5SDimitry Andric
650*cb14a3feSDimitry Andricpublic:
65106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg);
65206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg);
6530b57cec5SDimitry Andric
65406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& copy();
6550b57cec5SDimitry Andric};
6560b57cec5SDimitry Andric
6570b57cec5SDimitry Andrictemplate <class _Rp>
658*cb14a3feSDimitry Andricvoid __assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT {
6590b57cec5SDimitry Andric  delete this;
6600b57cec5SDimitry Andric}
6610b57cec5SDimitry Andric
6620b57cec5SDimitry Andrictemplate <class _Rp>
663*cb14a3feSDimitry Andricvoid __assoc_state<_Rp&>::set_value(_Rp& __arg) {
6640b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6650b57cec5SDimitry Andric  if (this->__has_value())
6660b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6675f757f3fSDimitry Andric  __value_ = std::addressof(__arg);
6680b57cec5SDimitry Andric  this->__state_ |= base::__constructed | base::ready;
6690b57cec5SDimitry Andric  __cv_.notify_all();
6700b57cec5SDimitry Andric}
6710b57cec5SDimitry Andric
6720b57cec5SDimitry Andrictemplate <class _Rp>
673*cb14a3feSDimitry Andricvoid __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) {
6740b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6750b57cec5SDimitry Andric  if (this->__has_value())
6760b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6775f757f3fSDimitry Andric  __value_ = std::addressof(__arg);
6780b57cec5SDimitry Andric  this->__state_ |= base::__constructed;
6790b57cec5SDimitry Andric  __thread_local_data()->__make_ready_at_thread_exit(this);
6800b57cec5SDimitry Andric}
6810b57cec5SDimitry Andric
6820b57cec5SDimitry Andrictemplate <class _Rp>
683*cb14a3feSDimitry Andric_Rp& __assoc_state<_Rp&>::copy() {
6840b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6850b57cec5SDimitry Andric  this->__sub_wait(__lk);
6860b57cec5SDimitry Andric  if (this->__exception_ != nullptr)
687bdd1243dSDimitry Andric    std::rethrow_exception(this->__exception_);
6880b57cec5SDimitry Andric  return *__value_;
6890b57cec5SDimitry Andric}
6900b57cec5SDimitry Andric
6910b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
692*cb14a3feSDimitry Andricclass __assoc_state_alloc : public __assoc_state<_Rp> {
6930b57cec5SDimitry Andric  typedef __assoc_state<_Rp> base;
6940b57cec5SDimitry Andric  _Alloc __alloc_;
6950b57cec5SDimitry Andric
69606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
697*cb14a3feSDimitry Andric
6980b57cec5SDimitry Andricpublic:
699*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
7000b57cec5SDimitry Andric};
7010b57cec5SDimitry Andric
7020b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
703*cb14a3feSDimitry Andricvoid __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT {
7040b57cec5SDimitry Andric  if (this->__state_ & base::__constructed)
7055f757f3fSDimitry Andric    reinterpret_cast<_Rp*>(std::addressof(this->__value_))->~_Rp();
7060b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
7070b57cec5SDimitry Andric  typedef allocator_traits<_Al> _ATraits;
7080b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7090b57cec5SDimitry Andric  _Al __a(__alloc_);
7100b57cec5SDimitry Andric  this->~__assoc_state_alloc();
7110b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
7120b57cec5SDimitry Andric}
7130b57cec5SDimitry Andric
7140b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
715*cb14a3feSDimitry Andricclass __assoc_state_alloc<_Rp&, _Alloc> : public __assoc_state<_Rp&> {
7160b57cec5SDimitry Andric  typedef __assoc_state<_Rp&> base;
7170b57cec5SDimitry Andric  _Alloc __alloc_;
7180b57cec5SDimitry Andric
71906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
720*cb14a3feSDimitry Andric
7210b57cec5SDimitry Andricpublic:
722*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
7230b57cec5SDimitry Andric};
7240b57cec5SDimitry Andric
7250b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
726*cb14a3feSDimitry Andricvoid __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT {
7270b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
7280b57cec5SDimitry Andric  typedef allocator_traits<_Al> _ATraits;
7290b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7300b57cec5SDimitry Andric  _Al __a(__alloc_);
7310b57cec5SDimitry Andric  this->~__assoc_state_alloc();
7320b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
7330b57cec5SDimitry Andric}
7340b57cec5SDimitry Andric
7350b57cec5SDimitry Andrictemplate <class _Alloc>
736*cb14a3feSDimitry Andricclass __assoc_sub_state_alloc : public __assoc_sub_state {
7370b57cec5SDimitry Andric  typedef __assoc_sub_state base;
7380b57cec5SDimitry Andric  _Alloc __alloc_;
7390b57cec5SDimitry Andric
74006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
741*cb14a3feSDimitry Andric
7420b57cec5SDimitry Andricpublic:
743*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_sub_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
7440b57cec5SDimitry Andric};
7450b57cec5SDimitry Andric
7460b57cec5SDimitry Andrictemplate <class _Alloc>
747*cb14a3feSDimitry Andricvoid __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT {
7480b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
7490b57cec5SDimitry Andric  typedef allocator_traits<_Al> _ATraits;
7500b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7510b57cec5SDimitry Andric  _Al __a(__alloc_);
7520b57cec5SDimitry Andric  this->~__assoc_sub_state_alloc();
7530b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
7540b57cec5SDimitry Andric}
7550b57cec5SDimitry Andric
7560b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
757*cb14a3feSDimitry Andricclass __deferred_assoc_state : public __assoc_state<_Rp> {
7580b57cec5SDimitry Andric  typedef __assoc_state<_Rp> base;
7590b57cec5SDimitry Andric
7600b57cec5SDimitry Andric  _Fp __func_;
7610b57cec5SDimitry Andric
7620b57cec5SDimitry Andricpublic:
763*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f);
7640b57cec5SDimitry Andric
76506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
7660b57cec5SDimitry Andric};
7670b57cec5SDimitry Andric
7680b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
769*cb14a3feSDimitry Andricinline __deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {
7700b57cec5SDimitry Andric  this->__set_deferred();
7710b57cec5SDimitry Andric}
7720b57cec5SDimitry Andric
7730b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
774*cb14a3feSDimitry Andricvoid __deferred_assoc_state<_Rp, _Fp>::__execute() {
77506c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
776*cb14a3feSDimitry Andric  try {
77706c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
7780b57cec5SDimitry Andric    this->set_value(__func_());
77906c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
780*cb14a3feSDimitry Andric  } catch (...) {
7810b57cec5SDimitry Andric    this->set_exception(current_exception());
7820b57cec5SDimitry Andric  }
78306c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
7840b57cec5SDimitry Andric}
7850b57cec5SDimitry Andric
7860b57cec5SDimitry Andrictemplate <class _Fp>
787*cb14a3feSDimitry Andricclass __deferred_assoc_state<void, _Fp> : public __assoc_sub_state {
7880b57cec5SDimitry Andric  typedef __assoc_sub_state base;
7890b57cec5SDimitry Andric
7900b57cec5SDimitry Andric  _Fp __func_;
7910b57cec5SDimitry Andric
7920b57cec5SDimitry Andricpublic:
793*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f);
7940b57cec5SDimitry Andric
79506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
7960b57cec5SDimitry Andric};
7970b57cec5SDimitry Andric
7980b57cec5SDimitry Andrictemplate <class _Fp>
799*cb14a3feSDimitry Andricinline __deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {
8000b57cec5SDimitry Andric  this->__set_deferred();
8010b57cec5SDimitry Andric}
8020b57cec5SDimitry Andric
8030b57cec5SDimitry Andrictemplate <class _Fp>
804*cb14a3feSDimitry Andricvoid __deferred_assoc_state<void, _Fp>::__execute() {
80506c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
806*cb14a3feSDimitry Andric  try {
80706c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8080b57cec5SDimitry Andric    __func_();
8090b57cec5SDimitry Andric    this->set_value();
81006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
811*cb14a3feSDimitry Andric  } catch (...) {
8120b57cec5SDimitry Andric    this->set_exception(current_exception());
8130b57cec5SDimitry Andric  }
81406c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8150b57cec5SDimitry Andric}
8160b57cec5SDimitry Andric
8170b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
818*cb14a3feSDimitry Andricclass __async_assoc_state : public __assoc_state<_Rp> {
8190b57cec5SDimitry Andric  typedef __assoc_state<_Rp> base;
8200b57cec5SDimitry Andric
8210b57cec5SDimitry Andric  _Fp __func_;
8220b57cec5SDimitry Andric
82306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
824*cb14a3feSDimitry Andric
8250b57cec5SDimitry Andricpublic:
826*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f);
8270b57cec5SDimitry Andric
82806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
8290b57cec5SDimitry Andric};
8300b57cec5SDimitry Andric
8310b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
832*cb14a3feSDimitry Andricinline __async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {}
8330b57cec5SDimitry Andric
8340b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
835*cb14a3feSDimitry Andricvoid __async_assoc_state<_Rp, _Fp>::__execute() {
83606c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
837*cb14a3feSDimitry Andric  try {
83806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8390b57cec5SDimitry Andric    this->set_value(__func_());
84006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
841*cb14a3feSDimitry Andric  } catch (...) {
8420b57cec5SDimitry Andric    this->set_exception(current_exception());
8430b57cec5SDimitry Andric  }
84406c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8450b57cec5SDimitry Andric}
8460b57cec5SDimitry Andric
8470b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
848*cb14a3feSDimitry Andricvoid __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT {
8490b57cec5SDimitry Andric  this->wait();
8500b57cec5SDimitry Andric  base::__on_zero_shared();
8510b57cec5SDimitry Andric}
8520b57cec5SDimitry Andric
8530b57cec5SDimitry Andrictemplate <class _Fp>
854*cb14a3feSDimitry Andricclass __async_assoc_state<void, _Fp> : public __assoc_sub_state {
8550b57cec5SDimitry Andric  typedef __assoc_sub_state base;
8560b57cec5SDimitry Andric
8570b57cec5SDimitry Andric  _Fp __func_;
8580b57cec5SDimitry Andric
85906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
860*cb14a3feSDimitry Andric
8610b57cec5SDimitry Andricpublic:
862*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f);
8630b57cec5SDimitry Andric
86406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
8650b57cec5SDimitry Andric};
8660b57cec5SDimitry Andric
8670b57cec5SDimitry Andrictemplate <class _Fp>
868*cb14a3feSDimitry Andricinline __async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {}
8690b57cec5SDimitry Andric
8700b57cec5SDimitry Andrictemplate <class _Fp>
871*cb14a3feSDimitry Andricvoid __async_assoc_state<void, _Fp>::__execute() {
87206c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
873*cb14a3feSDimitry Andric  try {
87406c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8750b57cec5SDimitry Andric    __func_();
8760b57cec5SDimitry Andric    this->set_value();
87706c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
878*cb14a3feSDimitry Andric  } catch (...) {
8790b57cec5SDimitry Andric    this->set_exception(current_exception());
8800b57cec5SDimitry Andric  }
88106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8820b57cec5SDimitry Andric}
8830b57cec5SDimitry Andric
8840b57cec5SDimitry Andrictemplate <class _Fp>
885*cb14a3feSDimitry Andricvoid __async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT {
8860b57cec5SDimitry Andric  this->wait();
8870b57cec5SDimitry Andric  base::__on_zero_shared();
8880b57cec5SDimitry Andric}
8890b57cec5SDimitry Andric
890*cb14a3feSDimitry Andrictemplate <class _Rp>
891*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise;
892*cb14a3feSDimitry Andrictemplate <class _Rp>
893*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future;
8940b57cec5SDimitry Andric
8950b57cec5SDimitry Andric// future
8960b57cec5SDimitry Andric
897*cb14a3feSDimitry Andrictemplate <class _Rp>
898*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future;
8990b57cec5SDimitry Andric
9000b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
901*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f);
9020b57cec5SDimitry Andric
9030b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
904*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f);
9050b57cec5SDimitry Andric
9060b57cec5SDimitry Andrictemplate <class _Rp>
907*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future {
9080b57cec5SDimitry Andric  __assoc_state<_Rp>* __state_;
9090b57cec5SDimitry Andric
91006c3fb27SDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state);
9110b57cec5SDimitry Andric
912*cb14a3feSDimitry Andric  template <class>
913*cb14a3feSDimitry Andric  friend class promise;
914*cb14a3feSDimitry Andric  template <class>
915*cb14a3feSDimitry Andric  friend class shared_future;
9160b57cec5SDimitry Andric
9170b57cec5SDimitry Andric  template <class _R1, class _Fp>
9180b57cec5SDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
9190b57cec5SDimitry Andric  template <class _R1, class _Fp>
9200b57cec5SDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
9210b57cec5SDimitry Andric
9220b57cec5SDimitry Andricpublic:
923*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
924*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
9250b57cec5SDimitry Andric  future(const future&)            = delete;
9260b57cec5SDimitry Andric  future& operator=(const future&) = delete;
927*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
9285f757f3fSDimitry Andric    future(std::move(__rhs)).swap(*this);
9290b57cec5SDimitry Andric    return *this;
9300b57cec5SDimitry Andric  }
931e8d8bef9SDimitry Andric
93206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~future();
933*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<_Rp> share() _NOEXCEPT;
9340b57cec5SDimitry Andric
9350b57cec5SDimitry Andric  // retrieving the value
93606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp get();
9370b57cec5SDimitry Andric
938*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
9390b57cec5SDimitry Andric
9400b57cec5SDimitry Andric  // functions to check state
941*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
9420b57cec5SDimitry Andric
943*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
9440b57cec5SDimitry Andric  template <class _Rep, class _Period>
945*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
946*cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
947*cb14a3feSDimitry Andric  }
9480b57cec5SDimitry Andric  template <class _Clock, class _Duration>
949*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
950*cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
951*cb14a3feSDimitry Andric  }
9520b57cec5SDimitry Andric};
9530b57cec5SDimitry Andric
9540b57cec5SDimitry Andrictemplate <class _Rp>
955*cb14a3feSDimitry Andricfuture<_Rp>::future(__assoc_state<_Rp>* __state) : __state_(__state) {
9560b57cec5SDimitry Andric  __state_->__attach_future();
9570b57cec5SDimitry Andric}
9580b57cec5SDimitry Andric
959*cb14a3feSDimitry Andricstruct __release_shared_count {
96006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) { __p->__release_shared(); }
9610b57cec5SDimitry Andric};
9620b57cec5SDimitry Andric
9630b57cec5SDimitry Andrictemplate <class _Rp>
964*cb14a3feSDimitry Andricfuture<_Rp>::~future() {
9650b57cec5SDimitry Andric  if (__state_)
9660b57cec5SDimitry Andric    __state_->__release_shared();
9670b57cec5SDimitry Andric}
9680b57cec5SDimitry Andric
9690b57cec5SDimitry Andrictemplate <class _Rp>
970*cb14a3feSDimitry Andric_Rp future<_Rp>::get() {
97106c3fb27SDimitry Andric  unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
9720b57cec5SDimitry Andric  __assoc_state<_Rp>* __s = __state_;
9730b57cec5SDimitry Andric  __state_                = nullptr;
9740b57cec5SDimitry Andric  return __s->move();
9750b57cec5SDimitry Andric}
9760b57cec5SDimitry Andric
9770b57cec5SDimitry Andrictemplate <class _Rp>
978*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future<_Rp&> {
9790b57cec5SDimitry Andric  __assoc_state<_Rp&>* __state_;
9800b57cec5SDimitry Andric
98106c3fb27SDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state);
9820b57cec5SDimitry Andric
983*cb14a3feSDimitry Andric  template <class>
984*cb14a3feSDimitry Andric  friend class promise;
985*cb14a3feSDimitry Andric  template <class>
986*cb14a3feSDimitry Andric  friend class shared_future;
9870b57cec5SDimitry Andric
9880b57cec5SDimitry Andric  template <class _R1, class _Fp>
9890b57cec5SDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
9900b57cec5SDimitry Andric  template <class _R1, class _Fp>
9910b57cec5SDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
9920b57cec5SDimitry Andric
9930b57cec5SDimitry Andricpublic:
994*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
995*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
9960b57cec5SDimitry Andric  future(const future&)            = delete;
9970b57cec5SDimitry Andric  future& operator=(const future&) = delete;
998*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
9995f757f3fSDimitry Andric    future(std::move(__rhs)).swap(*this);
10000b57cec5SDimitry Andric    return *this;
10010b57cec5SDimitry Andric  }
1002e8d8bef9SDimitry Andric
100306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~future();
1004*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<_Rp&> share() _NOEXCEPT;
10050b57cec5SDimitry Andric
10060b57cec5SDimitry Andric  // retrieving the value
100706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& get();
10080b57cec5SDimitry Andric
1009*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
10100b57cec5SDimitry Andric
10110b57cec5SDimitry Andric  // functions to check state
1012*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
10130b57cec5SDimitry Andric
1014*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
10150b57cec5SDimitry Andric  template <class _Rep, class _Period>
1016*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1017*cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1018*cb14a3feSDimitry Andric  }
10190b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1020*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1021*cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1022*cb14a3feSDimitry Andric  }
10230b57cec5SDimitry Andric};
10240b57cec5SDimitry Andric
10250b57cec5SDimitry Andrictemplate <class _Rp>
1026*cb14a3feSDimitry Andricfuture<_Rp&>::future(__assoc_state<_Rp&>* __state) : __state_(__state) {
10270b57cec5SDimitry Andric  __state_->__attach_future();
10280b57cec5SDimitry Andric}
10290b57cec5SDimitry Andric
10300b57cec5SDimitry Andrictemplate <class _Rp>
1031*cb14a3feSDimitry Andricfuture<_Rp&>::~future() {
10320b57cec5SDimitry Andric  if (__state_)
10330b57cec5SDimitry Andric    __state_->__release_shared();
10340b57cec5SDimitry Andric}
10350b57cec5SDimitry Andric
10360b57cec5SDimitry Andrictemplate <class _Rp>
1037*cb14a3feSDimitry Andric_Rp& future<_Rp&>::get() {
103806c3fb27SDimitry Andric  unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
10390b57cec5SDimitry Andric  __assoc_state<_Rp&>* __s = __state_;
10400b57cec5SDimitry Andric  __state_                 = nullptr;
10410b57cec5SDimitry Andric  return __s->copy();
10420b57cec5SDimitry Andric}
10430b57cec5SDimitry Andric
10440b57cec5SDimitry Andrictemplate <>
1045*cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future<void> {
10460b57cec5SDimitry Andric  __assoc_sub_state* __state_;
10470b57cec5SDimitry Andric
10480b57cec5SDimitry Andric  explicit future(__assoc_sub_state* __state);
10490b57cec5SDimitry Andric
1050*cb14a3feSDimitry Andric  template <class>
1051*cb14a3feSDimitry Andric  friend class promise;
1052*cb14a3feSDimitry Andric  template <class>
1053*cb14a3feSDimitry Andric  friend class shared_future;
10540b57cec5SDimitry Andric
10550b57cec5SDimitry Andric  template <class _R1, class _Fp>
10560b57cec5SDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
10570b57cec5SDimitry Andric  template <class _R1, class _Fp>
10580b57cec5SDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
10590b57cec5SDimitry Andric
10600b57cec5SDimitry Andricpublic:
1061*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
1062*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
10630b57cec5SDimitry Andric  future(const future&)            = delete;
10640b57cec5SDimitry Andric  future& operator=(const future&) = delete;
1065*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
10665f757f3fSDimitry Andric    future(std::move(__rhs)).swap(*this);
10670b57cec5SDimitry Andric    return *this;
10680b57cec5SDimitry Andric  }
1069e8d8bef9SDimitry Andric
10700b57cec5SDimitry Andric  ~future();
1071*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<void> share() _NOEXCEPT;
10720b57cec5SDimitry Andric
10730b57cec5SDimitry Andric  // retrieving the value
10740b57cec5SDimitry Andric  void get();
10750b57cec5SDimitry Andric
1076*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
10770b57cec5SDimitry Andric
10780b57cec5SDimitry Andric  // functions to check state
1079*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
10800b57cec5SDimitry Andric
1081*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
10820b57cec5SDimitry Andric  template <class _Rep, class _Period>
1083*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1084*cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1085*cb14a3feSDimitry Andric  }
10860b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1087*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1088*cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1089*cb14a3feSDimitry Andric  }
10900b57cec5SDimitry Andric};
10910b57cec5SDimitry Andric
10920b57cec5SDimitry Andrictemplate <class _Rp>
1093*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT {
10940b57cec5SDimitry Andric  __x.swap(__y);
10950b57cec5SDimitry Andric}
10960b57cec5SDimitry Andric
10970b57cec5SDimitry Andric// promise<R>
10980b57cec5SDimitry Andric
1099*cb14a3feSDimitry Andrictemplate <class _Callable>
1100*cb14a3feSDimitry Andricclass packaged_task;
11010b57cec5SDimitry Andric
11020b57cec5SDimitry Andrictemplate <class _Rp>
1103*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise {
11040b57cec5SDimitry Andric  __assoc_state<_Rp>* __state_;
11050b57cec5SDimitry Andric
1106*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
11070b57cec5SDimitry Andric
1108*cb14a3feSDimitry Andric  template <class>
1109*cb14a3feSDimitry Andric  friend class packaged_task;
1110*cb14a3feSDimitry Andric
11110b57cec5SDimitry Andricpublic:
111206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise();
11130b57cec5SDimitry Andric  template <class _Alloc>
111406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a);
1115*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
11160b57cec5SDimitry Andric  promise(const promise& __rhs) = delete;
111706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~promise();
11180b57cec5SDimitry Andric
11190b57cec5SDimitry Andric  // assignment
1120*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
11215f757f3fSDimitry Andric    promise(std::move(__rhs)).swap(*this);
11220b57cec5SDimitry Andric    return *this;
11230b57cec5SDimitry Andric  }
11240b57cec5SDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1125e8d8bef9SDimitry Andric
1126*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
11270b57cec5SDimitry Andric
11280b57cec5SDimitry Andric  // retrieving the result
112906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future();
11300b57cec5SDimitry Andric
11310b57cec5SDimitry Andric  // setting the result
113206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r);
113306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r);
113406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
11350b57cec5SDimitry Andric
11360b57cec5SDimitry Andric  // setting the result with deferred notification
113706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r);
113806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r);
113906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
11400b57cec5SDimitry Andric};
11410b57cec5SDimitry Andric
11420b57cec5SDimitry Andrictemplate <class _Rp>
1143*cb14a3feSDimitry Andricpromise<_Rp>::promise() : __state_(new __assoc_state<_Rp>) {}
11440b57cec5SDimitry Andric
11450b57cec5SDimitry Andrictemplate <class _Rp>
11460b57cec5SDimitry Andrictemplate <class _Alloc>
1147*cb14a3feSDimitry Andricpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) {
11480b57cec5SDimitry Andric  typedef __assoc_state_alloc<_Rp, _Alloc> _State;
11490b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
11500b57cec5SDimitry Andric  typedef __allocator_destructor<_A2> _D2;
11510b57cec5SDimitry Andric  _A2 __a(__a0);
11520b57cec5SDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
11535f757f3fSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
11545f757f3fSDimitry Andric  __state_ = std::addressof(*__hold.release());
11550b57cec5SDimitry Andric}
11560b57cec5SDimitry Andric
11570b57cec5SDimitry Andrictemplate <class _Rp>
1158*cb14a3feSDimitry Andricpromise<_Rp>::~promise() {
1159*cb14a3feSDimitry Andric  if (__state_) {
11600b57cec5SDimitry Andric    if (!__state_->__has_value() && __state_->use_count() > 1)
11615f757f3fSDimitry Andric      __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise))));
11620b57cec5SDimitry Andric    __state_->__release_shared();
11630b57cec5SDimitry Andric  }
11640b57cec5SDimitry Andric}
11650b57cec5SDimitry Andric
11660b57cec5SDimitry Andrictemplate <class _Rp>
1167*cb14a3feSDimitry Andricfuture<_Rp> promise<_Rp>::get_future() {
11680b57cec5SDimitry Andric  if (__state_ == nullptr)
11690b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11700b57cec5SDimitry Andric  return future<_Rp>(__state_);
11710b57cec5SDimitry Andric}
11720b57cec5SDimitry Andric
11730b57cec5SDimitry Andrictemplate <class _Rp>
1174*cb14a3feSDimitry Andricvoid promise<_Rp>::set_value(const _Rp& __r) {
11750b57cec5SDimitry Andric  if (__state_ == nullptr)
11760b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11770b57cec5SDimitry Andric  __state_->set_value(__r);
11780b57cec5SDimitry Andric}
11790b57cec5SDimitry Andric
11800b57cec5SDimitry Andrictemplate <class _Rp>
1181*cb14a3feSDimitry Andricvoid promise<_Rp>::set_value(_Rp&& __r) {
11820b57cec5SDimitry Andric  if (__state_ == nullptr)
11830b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11845f757f3fSDimitry Andric  __state_->set_value(std::move(__r));
11850b57cec5SDimitry Andric}
11860b57cec5SDimitry Andric
11870b57cec5SDimitry Andrictemplate <class _Rp>
1188*cb14a3feSDimitry Andricvoid promise<_Rp>::set_exception(exception_ptr __p) {
11895f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr");
11900b57cec5SDimitry Andric  if (__state_ == nullptr)
11910b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11920b57cec5SDimitry Andric  __state_->set_exception(__p);
11930b57cec5SDimitry Andric}
11940b57cec5SDimitry Andric
11950b57cec5SDimitry Andrictemplate <class _Rp>
1196*cb14a3feSDimitry Andricvoid promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) {
11970b57cec5SDimitry Andric  if (__state_ == nullptr)
11980b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11990b57cec5SDimitry Andric  __state_->set_value_at_thread_exit(__r);
12000b57cec5SDimitry Andric}
12010b57cec5SDimitry Andric
12020b57cec5SDimitry Andrictemplate <class _Rp>
1203*cb14a3feSDimitry Andricvoid promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) {
12040b57cec5SDimitry Andric  if (__state_ == nullptr)
12050b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12065f757f3fSDimitry Andric  __state_->set_value_at_thread_exit(std::move(__r));
12070b57cec5SDimitry Andric}
12080b57cec5SDimitry Andric
12090b57cec5SDimitry Andrictemplate <class _Rp>
1210*cb14a3feSDimitry Andricvoid promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) {
12115f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr");
12120b57cec5SDimitry Andric  if (__state_ == nullptr)
12130b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12140b57cec5SDimitry Andric  __state_->set_exception_at_thread_exit(__p);
12150b57cec5SDimitry Andric}
12160b57cec5SDimitry Andric
12170b57cec5SDimitry Andric// promise<R&>
12180b57cec5SDimitry Andric
12190b57cec5SDimitry Andrictemplate <class _Rp>
1220*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise<_Rp&> {
12210b57cec5SDimitry Andric  __assoc_state<_Rp&>* __state_;
12220b57cec5SDimitry Andric
1223*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
12240b57cec5SDimitry Andric
1225*cb14a3feSDimitry Andric  template <class>
1226*cb14a3feSDimitry Andric  friend class packaged_task;
12270b57cec5SDimitry Andric
12280b57cec5SDimitry Andricpublic:
122906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise();
12300b57cec5SDimitry Andric  template <class _Allocator>
123106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a);
1232*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
12330b57cec5SDimitry Andric  promise(const promise& __rhs) = delete;
123406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~promise();
12350b57cec5SDimitry Andric
12360b57cec5SDimitry Andric  // assignment
1237*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
12385f757f3fSDimitry Andric    promise(std::move(__rhs)).swap(*this);
12390b57cec5SDimitry Andric    return *this;
12400b57cec5SDimitry Andric  }
12410b57cec5SDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1242e8d8bef9SDimitry Andric
1243*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
12440b57cec5SDimitry Andric
12450b57cec5SDimitry Andric  // retrieving the result
124606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future();
12470b57cec5SDimitry Andric
12480b57cec5SDimitry Andric  // setting the result
124906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r);
125006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
12510b57cec5SDimitry Andric
12520b57cec5SDimitry Andric  // setting the result with deferred notification
125306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&);
125406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
12550b57cec5SDimitry Andric};
12560b57cec5SDimitry Andric
12570b57cec5SDimitry Andrictemplate <class _Rp>
1258*cb14a3feSDimitry Andricpromise<_Rp&>::promise() : __state_(new __assoc_state<_Rp&>) {}
12590b57cec5SDimitry Andric
12600b57cec5SDimitry Andrictemplate <class _Rp>
12610b57cec5SDimitry Andrictemplate <class _Alloc>
1262*cb14a3feSDimitry Andricpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) {
12630b57cec5SDimitry Andric  typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
12640b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
12650b57cec5SDimitry Andric  typedef __allocator_destructor<_A2> _D2;
12660b57cec5SDimitry Andric  _A2 __a(__a0);
12670b57cec5SDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
12685f757f3fSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
12695f757f3fSDimitry Andric  __state_ = std::addressof(*__hold.release());
12700b57cec5SDimitry Andric}
12710b57cec5SDimitry Andric
12720b57cec5SDimitry Andrictemplate <class _Rp>
1273*cb14a3feSDimitry Andricpromise<_Rp&>::~promise() {
1274*cb14a3feSDimitry Andric  if (__state_) {
12750b57cec5SDimitry Andric    if (!__state_->__has_value() && __state_->use_count() > 1)
12765f757f3fSDimitry Andric      __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise))));
12770b57cec5SDimitry Andric    __state_->__release_shared();
12780b57cec5SDimitry Andric  }
12790b57cec5SDimitry Andric}
12800b57cec5SDimitry Andric
12810b57cec5SDimitry Andrictemplate <class _Rp>
1282*cb14a3feSDimitry Andricfuture<_Rp&> promise<_Rp&>::get_future() {
12830b57cec5SDimitry Andric  if (__state_ == nullptr)
12840b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12850b57cec5SDimitry Andric  return future<_Rp&>(__state_);
12860b57cec5SDimitry Andric}
12870b57cec5SDimitry Andric
12880b57cec5SDimitry Andrictemplate <class _Rp>
1289*cb14a3feSDimitry Andricvoid promise<_Rp&>::set_value(_Rp& __r) {
12900b57cec5SDimitry Andric  if (__state_ == nullptr)
12910b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12920b57cec5SDimitry Andric  __state_->set_value(__r);
12930b57cec5SDimitry Andric}
12940b57cec5SDimitry Andric
12950b57cec5SDimitry Andrictemplate <class _Rp>
1296*cb14a3feSDimitry Andricvoid promise<_Rp&>::set_exception(exception_ptr __p) {
12975f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr");
12980b57cec5SDimitry Andric  if (__state_ == nullptr)
12990b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
13000b57cec5SDimitry Andric  __state_->set_exception(__p);
13010b57cec5SDimitry Andric}
13020b57cec5SDimitry Andric
13030b57cec5SDimitry Andrictemplate <class _Rp>
1304*cb14a3feSDimitry Andricvoid promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) {
13050b57cec5SDimitry Andric  if (__state_ == nullptr)
13060b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
13070b57cec5SDimitry Andric  __state_->set_value_at_thread_exit(__r);
13080b57cec5SDimitry Andric}
13090b57cec5SDimitry Andric
13100b57cec5SDimitry Andrictemplate <class _Rp>
1311*cb14a3feSDimitry Andricvoid promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) {
13125f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr");
13130b57cec5SDimitry Andric  if (__state_ == nullptr)
13140b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
13150b57cec5SDimitry Andric  __state_->set_exception_at_thread_exit(__p);
13160b57cec5SDimitry Andric}
13170b57cec5SDimitry Andric
13180b57cec5SDimitry Andric// promise<void>
13190b57cec5SDimitry Andric
13200b57cec5SDimitry Andrictemplate <>
1321*cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI promise<void> {
13220b57cec5SDimitry Andric  __assoc_sub_state* __state_;
13230b57cec5SDimitry Andric
1324*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
13250b57cec5SDimitry Andric
1326*cb14a3feSDimitry Andric  template <class>
1327*cb14a3feSDimitry Andric  friend class packaged_task;
13280b57cec5SDimitry Andric
13290b57cec5SDimitry Andricpublic:
13300b57cec5SDimitry Andric  promise();
13310b57cec5SDimitry Andric  template <class _Allocator>
1332*cb14a3feSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS promise(allocator_arg_t, const _Allocator& __a);
1333*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
13340b57cec5SDimitry Andric  promise(const promise& __rhs) = delete;
13350b57cec5SDimitry Andric  ~promise();
13360b57cec5SDimitry Andric
13370b57cec5SDimitry Andric  // assignment
1338*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
13395f757f3fSDimitry Andric    promise(std::move(__rhs)).swap(*this);
13400b57cec5SDimitry Andric    return *this;
13410b57cec5SDimitry Andric  }
13420b57cec5SDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1343e8d8bef9SDimitry Andric
1344*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
13450b57cec5SDimitry Andric
13460b57cec5SDimitry Andric  // retrieving the result
13470b57cec5SDimitry Andric  future<void> get_future();
13480b57cec5SDimitry Andric
13490b57cec5SDimitry Andric  // setting the result
13500b57cec5SDimitry Andric  void set_value();
13510b57cec5SDimitry Andric  void set_exception(exception_ptr __p);
13520b57cec5SDimitry Andric
13530b57cec5SDimitry Andric  // setting the result with deferred notification
13540b57cec5SDimitry Andric  void set_value_at_thread_exit();
13550b57cec5SDimitry Andric  void set_exception_at_thread_exit(exception_ptr __p);
13560b57cec5SDimitry Andric};
13570b57cec5SDimitry Andric
13580b57cec5SDimitry Andrictemplate <class _Alloc>
1359*cb14a3feSDimitry Andricpromise<void>::promise(allocator_arg_t, const _Alloc& __a0) {
13600b57cec5SDimitry Andric  typedef __assoc_sub_state_alloc<_Alloc> _State;
13610b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
13620b57cec5SDimitry Andric  typedef __allocator_destructor<_A2> _D2;
13630b57cec5SDimitry Andric  _A2 __a(__a0);
13640b57cec5SDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
13655f757f3fSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
13665f757f3fSDimitry Andric  __state_ = std::addressof(*__hold.release());
13670b57cec5SDimitry Andric}
13680b57cec5SDimitry Andric
13690b57cec5SDimitry Andrictemplate <class _Rp>
1370*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT {
13710b57cec5SDimitry Andric  __x.swap(__y);
13720b57cec5SDimitry Andric}
13730b57cec5SDimitry Andric
13740b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
1375*cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc> : public true_type {};
13760b57cec5SDimitry Andric
13770b57cec5SDimitry Andric// packaged_task
13780b57cec5SDimitry Andric
1379*cb14a3feSDimitry Andrictemplate <class _Fp>
1380*cb14a3feSDimitry Andricclass __packaged_task_base;
13810b57cec5SDimitry Andric
13820b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1383*cb14a3feSDimitry Andricclass __packaged_task_base<_Rp(_ArgTypes...)> {
13840b57cec5SDimitry Andric  __packaged_task_base(const __packaged_task_base&);
13850b57cec5SDimitry Andric  __packaged_task_base& operator=(const __packaged_task_base&);
1386*cb14a3feSDimitry Andric
13870b57cec5SDimitry Andricpublic:
1388*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_base() {}
1389bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL
13900b57cec5SDimitry Andric  virtual ~__packaged_task_base() {}
13910b57cec5SDimitry Andric  virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
13920b57cec5SDimitry Andric  virtual void destroy()                                  = 0;
13930b57cec5SDimitry Andric  virtual void destroy_deallocate()                       = 0;
13940b57cec5SDimitry Andric  virtual _Rp operator()(_ArgTypes&&...)                  = 0;
13950b57cec5SDimitry Andric};
13960b57cec5SDimitry Andric
1397*cb14a3feSDimitry Andrictemplate <class _FD, class _Alloc, class _FB>
1398*cb14a3feSDimitry Andricclass __packaged_task_func;
13990b57cec5SDimitry Andric
14000b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1401*cb14a3feSDimitry Andricclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __packaged_task_base<_Rp(_ArgTypes...)> {
14020b57cec5SDimitry Andric  __compressed_pair<_Fp, _Alloc> __f_;
1403*cb14a3feSDimitry Andric
14040b57cec5SDimitry Andricpublic:
1405*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
1406*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(_Fp&& __f) : __f_(std::move(__f), __default_init_tag()) {}
1407*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {}
1408*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_func(_Fp&& __f, const _Alloc& __a) : __f_(std::move(__f), __a) {}
140906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
141006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy();
141106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate();
141206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __args);
14130b57cec5SDimitry Andric};
14140b57cec5SDimitry Andric
14150b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1416*cb14a3feSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1417*cb14a3feSDimitry Andric    __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT {
14185f757f3fSDimitry Andric  ::new ((void*)__p) __packaged_task_func(std::move(__f_.first()), std::move(__f_.second()));
14190b57cec5SDimitry Andric}
14200b57cec5SDimitry Andric
14210b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1422*cb14a3feSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() {
14230b57cec5SDimitry Andric  __f_.~__compressed_pair<_Fp, _Alloc>();
14240b57cec5SDimitry Andric}
14250b57cec5SDimitry Andric
14260b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1427*cb14a3feSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() {
14280b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
14290b57cec5SDimitry Andric  typedef allocator_traits<_Ap> _ATraits;
14300b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
14310b57cec5SDimitry Andric  _Ap __a(__f_.second());
14320b57cec5SDimitry Andric  __f_.~__compressed_pair<_Fp, _Alloc>();
14330b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
14340b57cec5SDimitry Andric}
14350b57cec5SDimitry Andric
14360b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1437*cb14a3feSDimitry Andric_Rp __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) {
14385f757f3fSDimitry Andric  return std::__invoke(__f_.first(), std::forward<_ArgTypes>(__arg)...);
14390b57cec5SDimitry Andric}
14400b57cec5SDimitry Andric
1441*cb14a3feSDimitry Andrictemplate <class _Callable>
1442*cb14a3feSDimitry Andricclass __packaged_task_function;
14430b57cec5SDimitry Andric
14440b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1445*cb14a3feSDimitry Andricclass __packaged_task_function<_Rp(_ArgTypes...)> {
14460b57cec5SDimitry Andric  typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1447e8d8bef9SDimitry Andric
1448*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __base* __get_buf() { return (__base*)&__buf_; }
1449e8d8bef9SDimitry Andric
1450bdd1243dSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
14510b57cec5SDimitry Andric  typename aligned_storage<3 * sizeof(void*)>::type __buf_;
1452bdd1243dSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_POP
14530b57cec5SDimitry Andric  __base* __f_;
14540b57cec5SDimitry Andric
14550b57cec5SDimitry Andricpublic:
14560b57cec5SDimitry Andric  typedef _Rp result_type;
14570b57cec5SDimitry Andric
14580b57cec5SDimitry Andric  // construct/copy/destroy:
1459*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
14600b57cec5SDimitry Andric  template <class _Fp>
146106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f);
14620b57cec5SDimitry Andric  template <class _Fp, class _Alloc>
146306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
14640b57cec5SDimitry Andric
146506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
146606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
14670b57cec5SDimitry Andric
14680b57cec5SDimitry Andric  __packaged_task_function(const __packaged_task_function&)            = delete;
14690b57cec5SDimitry Andric  __packaged_task_function& operator=(const __packaged_task_function&) = delete;
14700b57cec5SDimitry Andric
147106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function();
14720b57cec5SDimitry Andric
147306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT;
14740b57cec5SDimitry Andric
1475*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
14760b57cec5SDimitry Andric};
14770b57cec5SDimitry Andric
14780b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1479*cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT {
14800b57cec5SDimitry Andric  if (__f.__f_ == nullptr)
14810b57cec5SDimitry Andric    __f_ = nullptr;
1482*cb14a3feSDimitry Andric  else if (__f.__f_ == __f.__get_buf()) {
1483e8d8bef9SDimitry Andric    __f.__f_->__move_to(__get_buf());
14840b57cec5SDimitry Andric    __f_ = (__base*)&__buf_;
1485*cb14a3feSDimitry Andric  } else {
14860b57cec5SDimitry Andric    __f_     = __f.__f_;
14870b57cec5SDimitry Andric    __f.__f_ = nullptr;
14880b57cec5SDimitry Andric  }
14890b57cec5SDimitry Andric}
14900b57cec5SDimitry Andric
14910b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
14920b57cec5SDimitry Andrictemplate <class _Fp>
1493*cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) : __f_(nullptr) {
149406c3fb27SDimitry Andric  typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
14950b57cec5SDimitry Andric  typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1496*cb14a3feSDimitry Andric  if (sizeof(_FF) <= sizeof(__buf_)) {
14975f757f3fSDimitry Andric    ::new ((void*)&__buf_) _FF(std::forward<_Fp>(__f));
14980b57cec5SDimitry Andric    __f_ = (__base*)&__buf_;
1499*cb14a3feSDimitry Andric  } else {
15000b57cec5SDimitry Andric    typedef allocator<_FF> _Ap;
15010b57cec5SDimitry Andric    _Ap __a;
15020b57cec5SDimitry Andric    typedef __allocator_destructor<_Ap> _Dp;
15030b57cec5SDimitry Andric    unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
15045f757f3fSDimitry Andric    ::new ((void*)__hold.get()) _FF(std::forward<_Fp>(__f), allocator<_FR>(__a));
15050b57cec5SDimitry Andric    __f_ = __hold.release();
15060b57cec5SDimitry Andric  }
15070b57cec5SDimitry Andric}
15080b57cec5SDimitry Andric
15090b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
15100b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc>
1511*cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1512*cb14a3feSDimitry Andric    : __f_(nullptr) {
151306c3fb27SDimitry Andric  typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
15140b57cec5SDimitry Andric  typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1515*cb14a3feSDimitry Andric  if (sizeof(_FF) <= sizeof(__buf_)) {
15160b57cec5SDimitry Andric    __f_ = (__base*)&__buf_;
15175f757f3fSDimitry Andric    ::new ((void*)__f_) _FF(std::forward<_Fp>(__f));
1518*cb14a3feSDimitry Andric  } else {
15190b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
15200b57cec5SDimitry Andric    _Ap __a(__a0);
15210b57cec5SDimitry Andric    typedef __allocator_destructor<_Ap> _Dp;
15220b57cec5SDimitry Andric    unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1523*cb14a3feSDimitry Andric    ::new ((void*)std::addressof(*__hold.get())) _FF(std::forward<_Fp>(__f), _Alloc(__a));
15245f757f3fSDimitry Andric    __f_ = std::addressof(*__hold.release());
15250b57cec5SDimitry Andric  }
15260b57cec5SDimitry Andric}
15270b57cec5SDimitry Andric
15280b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
15290b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>&
1530*cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT {
1531e8d8bef9SDimitry Andric  if (__f_ == __get_buf())
15320b57cec5SDimitry Andric    __f_->destroy();
15330b57cec5SDimitry Andric  else if (__f_)
15340b57cec5SDimitry Andric    __f_->destroy_deallocate();
15350b57cec5SDimitry Andric  __f_ = nullptr;
15360b57cec5SDimitry Andric  if (__f.__f_ == nullptr)
15370b57cec5SDimitry Andric    __f_ = nullptr;
1538*cb14a3feSDimitry Andric  else if (__f.__f_ == __f.__get_buf()) {
1539e8d8bef9SDimitry Andric    __f.__f_->__move_to(__get_buf());
1540e8d8bef9SDimitry Andric    __f_ = __get_buf();
1541*cb14a3feSDimitry Andric  } else {
15420b57cec5SDimitry Andric    __f_     = __f.__f_;
15430b57cec5SDimitry Andric    __f.__f_ = nullptr;
15440b57cec5SDimitry Andric  }
15450b57cec5SDimitry Andric  return *this;
15460b57cec5SDimitry Andric}
15470b57cec5SDimitry Andric
15480b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1549*cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() {
1550e8d8bef9SDimitry Andric  if (__f_ == __get_buf())
15510b57cec5SDimitry Andric    __f_->destroy();
15520b57cec5SDimitry Andric  else if (__f_)
15530b57cec5SDimitry Andric    __f_->destroy_deallocate();
15540b57cec5SDimitry Andric}
15550b57cec5SDimitry Andric
15560b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1557*cb14a3feSDimitry Andric_LIBCPP_NO_CFI void __packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT {
1558*cb14a3feSDimitry Andric  if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) {
1559bdd1243dSDimitry Andric    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
15600b57cec5SDimitry Andric    typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1561bdd1243dSDimitry Andric    _LIBCPP_SUPPRESS_DEPRECATED_POP
15620b57cec5SDimitry Andric    __base* __t = (__base*)&__tempbuf;
15630b57cec5SDimitry Andric    __f_->__move_to(__t);
15640b57cec5SDimitry Andric    __f_->destroy();
15650b57cec5SDimitry Andric    __f_ = nullptr;
15660b57cec5SDimitry Andric    __f.__f_->__move_to((__base*)&__buf_);
15670b57cec5SDimitry Andric    __f.__f_->destroy();
15680b57cec5SDimitry Andric    __f.__f_ = nullptr;
15690b57cec5SDimitry Andric    __f_     = (__base*)&__buf_;
15700b57cec5SDimitry Andric    __t->__move_to((__base*)&__f.__buf_);
15710b57cec5SDimitry Andric    __t->destroy();
15720b57cec5SDimitry Andric    __f.__f_ = (__base*)&__f.__buf_;
1573*cb14a3feSDimitry Andric  } else if (__f_ == (__base*)&__buf_) {
15740b57cec5SDimitry Andric    __f_->__move_to((__base*)&__f.__buf_);
15750b57cec5SDimitry Andric    __f_->destroy();
15760b57cec5SDimitry Andric    __f_     = __f.__f_;
15770b57cec5SDimitry Andric    __f.__f_ = (__base*)&__f.__buf_;
1578*cb14a3feSDimitry Andric  } else if (__f.__f_ == (__base*)&__f.__buf_) {
15790b57cec5SDimitry Andric    __f.__f_->__move_to((__base*)&__buf_);
15800b57cec5SDimitry Andric    __f.__f_->destroy();
15810b57cec5SDimitry Andric    __f.__f_ = __f_;
15820b57cec5SDimitry Andric    __f_     = (__base*)&__buf_;
1583*cb14a3feSDimitry Andric  } else
15845f757f3fSDimitry Andric    std::swap(__f_, __f.__f_);
15850b57cec5SDimitry Andric}
15860b57cec5SDimitry Andric
15870b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1588*cb14a3feSDimitry Andricinline _Rp __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const {
15895f757f3fSDimitry Andric  return (*__f_)(std::forward<_ArgTypes>(__arg)...);
15900b57cec5SDimitry Andric}
15910b57cec5SDimitry Andric
15920b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1593*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<_Rp(_ArgTypes...)> {
15940b57cec5SDimitry Andricpublic:
15950b57cec5SDimitry Andric  typedef _Rp result_type; // extension
15960b57cec5SDimitry Andric
15970b57cec5SDimitry Andricprivate:
15980b57cec5SDimitry Andric  __packaged_task_function<result_type(_ArgTypes...)> __f_;
15990b57cec5SDimitry Andric  promise<result_type> __p_;
16000b57cec5SDimitry Andric
16010b57cec5SDimitry Andricpublic:
16020b57cec5SDimitry Andric  // construction and destruction
1603*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}
1604*cb14a3feSDimitry Andric  template <class _Fp, class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
1605*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
1606*cb14a3feSDimitry Andric  template <class _Fp, class _Allocator, class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
1607*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1608*cb14a3feSDimitry Andric      : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
16090b57cec5SDimitry Andric  // ~packaged_task() = default;
16100b57cec5SDimitry Andric
16110b57cec5SDimitry Andric  // no copy
16120b57cec5SDimitry Andric  packaged_task(const packaged_task&)            = delete;
16130b57cec5SDimitry Andric  packaged_task& operator=(const packaged_task&) = delete;
16140b57cec5SDimitry Andric
16150b57cec5SDimitry Andric  // move support
1616*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT
1617*cb14a3feSDimitry Andric      : __f_(std::move(__other.__f_)),
1618*cb14a3feSDimitry Andric        __p_(std::move(__other.__p_)) {}
1619*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT {
16205f757f3fSDimitry Andric    __f_ = std::move(__other.__f_);
16215f757f3fSDimitry Andric    __p_ = std::move(__other.__p_);
16220b57cec5SDimitry Andric    return *this;
16230b57cec5SDimitry Andric  }
1624*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT {
16250b57cec5SDimitry Andric    __f_.swap(__other.__f_);
16260b57cec5SDimitry Andric    __p_.swap(__other.__p_);
16270b57cec5SDimitry Andric  }
16280b57cec5SDimitry Andric
1629*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
16300b57cec5SDimitry Andric
16310b57cec5SDimitry Andric  // result retrieval
1632*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); }
16330b57cec5SDimitry Andric
16340b57cec5SDimitry Andric  // execution
163506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
163606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
16370b57cec5SDimitry Andric
163806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reset();
16390b57cec5SDimitry Andric};
16400b57cec5SDimitry Andric
16410b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1642*cb14a3feSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) {
16430b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
16440b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
16450b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
16460b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
164706c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1648*cb14a3feSDimitry Andric  try {
164906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16505f757f3fSDimitry Andric    __p_.set_value(__f_(std::forward<_ArgTypes>(__args)...));
165106c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1652*cb14a3feSDimitry Andric  } catch (...) {
16530b57cec5SDimitry Andric    __p_.set_exception(current_exception());
16540b57cec5SDimitry Andric  }
165506c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16560b57cec5SDimitry Andric}
16570b57cec5SDimitry Andric
16580b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1659*cb14a3feSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {
16600b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
16610b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
16620b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
16630b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
166406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1665*cb14a3feSDimitry Andric  try {
166606c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16675f757f3fSDimitry Andric    __p_.set_value_at_thread_exit(__f_(std::forward<_ArgTypes>(__args)...));
166806c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1669*cb14a3feSDimitry Andric  } catch (...) {
16700b57cec5SDimitry Andric    __p_.set_exception_at_thread_exit(current_exception());
16710b57cec5SDimitry Andric  }
167206c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
16730b57cec5SDimitry Andric}
16740b57cec5SDimitry Andric
16750b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1676*cb14a3feSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::reset() {
16770b57cec5SDimitry Andric  if (!valid())
16780b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
16790b57cec5SDimitry Andric  __p_ = promise<result_type>();
16800b57cec5SDimitry Andric}
16810b57cec5SDimitry Andric
16820b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1683*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<void(_ArgTypes...)> {
16840b57cec5SDimitry Andricpublic:
16850b57cec5SDimitry Andric  typedef void result_type; // extension
16860b57cec5SDimitry Andric
16870b57cec5SDimitry Andricprivate:
16880b57cec5SDimitry Andric  __packaged_task_function<result_type(_ArgTypes...)> __f_;
16890b57cec5SDimitry Andric  promise<result_type> __p_;
16900b57cec5SDimitry Andric
16910b57cec5SDimitry Andricpublic:
16920b57cec5SDimitry Andric  // construction and destruction
1693*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}
1694*cb14a3feSDimitry Andric  template <class _Fp, class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
1695*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
1696*cb14a3feSDimitry Andric  template <class _Fp, class _Allocator, class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
1697*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1698*cb14a3feSDimitry Andric      : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
16990b57cec5SDimitry Andric  // ~packaged_task() = default;
17000b57cec5SDimitry Andric
17010b57cec5SDimitry Andric  // no copy
17020b57cec5SDimitry Andric  packaged_task(const packaged_task&)            = delete;
17030b57cec5SDimitry Andric  packaged_task& operator=(const packaged_task&) = delete;
17040b57cec5SDimitry Andric
17050b57cec5SDimitry Andric  // move support
1706*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT
1707*cb14a3feSDimitry Andric      : __f_(std::move(__other.__f_)),
1708*cb14a3feSDimitry Andric        __p_(std::move(__other.__p_)) {}
1709*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT {
17105f757f3fSDimitry Andric    __f_ = std::move(__other.__f_);
17115f757f3fSDimitry Andric    __p_ = std::move(__other.__p_);
17120b57cec5SDimitry Andric    return *this;
17130b57cec5SDimitry Andric  }
1714*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT {
17150b57cec5SDimitry Andric    __f_.swap(__other.__f_);
17160b57cec5SDimitry Andric    __p_.swap(__other.__p_);
17170b57cec5SDimitry Andric  }
17180b57cec5SDimitry Andric
1719*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
17200b57cec5SDimitry Andric
17210b57cec5SDimitry Andric  // result retrieval
1722*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); }
17230b57cec5SDimitry Andric
17240b57cec5SDimitry Andric  // execution
172506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
172606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
17270b57cec5SDimitry Andric
172806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reset();
17290b57cec5SDimitry Andric};
17300b57cec5SDimitry Andric
1731bdd1243dSDimitry Andric#if _LIBCPP_STD_VER >= 17
1732bdd1243dSDimitry Andric
1733bdd1243dSDimitry Andrictemplate <class _Rp, class... _Args>
1734bdd1243dSDimitry Andricpackaged_task(_Rp (*)(_Args...)) -> packaged_task<_Rp(_Args...)>;
1735bdd1243dSDimitry Andric
1736bdd1243dSDimitry Andrictemplate <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
1737bdd1243dSDimitry Andricpackaged_task(_Fp) -> packaged_task<_Stripped>;
1738bdd1243dSDimitry Andric
1739bdd1243dSDimitry Andric#endif
1740bdd1243dSDimitry Andric
17410b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1742*cb14a3feSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) {
17430b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
17440b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
17450b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
17460b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
174706c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1748*cb14a3feSDimitry Andric  try {
174906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17505f757f3fSDimitry Andric    __f_(std::forward<_ArgTypes>(__args)...);
17510b57cec5SDimitry Andric    __p_.set_value();
175206c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1753*cb14a3feSDimitry Andric  } catch (...) {
17540b57cec5SDimitry Andric    __p_.set_exception(current_exception());
17550b57cec5SDimitry Andric  }
175606c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17570b57cec5SDimitry Andric}
17580b57cec5SDimitry Andric
17590b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1760*cb14a3feSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {
17610b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
17620b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
17630b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
17640b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
176506c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1766*cb14a3feSDimitry Andric  try {
176706c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17685f757f3fSDimitry Andric    __f_(std::forward<_ArgTypes>(__args)...);
17690b57cec5SDimitry Andric    __p_.set_value_at_thread_exit();
177006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1771*cb14a3feSDimitry Andric  } catch (...) {
17720b57cec5SDimitry Andric    __p_.set_exception_at_thread_exit(current_exception());
17730b57cec5SDimitry Andric  }
177406c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
17750b57cec5SDimitry Andric}
17760b57cec5SDimitry Andric
17770b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1778*cb14a3feSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::reset() {
17790b57cec5SDimitry Andric  if (!valid())
17800b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
17810b57cec5SDimitry Andric  __p_ = promise<result_type>();
17820b57cec5SDimitry Andric}
17830b57cec5SDimitry Andric
1784fe6060f1SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1785*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
1786*cb14a3feSDimitry Andricswap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT {
17870b57cec5SDimitry Andric  __x.swap(__y);
17880b57cec5SDimitry Andric}
17890b57cec5SDimitry Andric
17900b57cec5SDimitry Andrictemplate <class _Callable, class _Alloc>
1791*cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {};
17920b57cec5SDimitry Andric
17930b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1794*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f) {
1795*cb14a3feSDimitry Andric  unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
1796*cb14a3feSDimitry Andric      new __deferred_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
17970b57cec5SDimitry Andric  return future<_Rp>(__h.get());
17980b57cec5SDimitry Andric}
17990b57cec5SDimitry Andric
18000b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1801*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f) {
1802*cb14a3feSDimitry Andric  unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
1803*cb14a3feSDimitry Andric      new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
18045f757f3fSDimitry Andric  std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
18050b57cec5SDimitry Andric  return future<_Rp>(__h.get());
18060b57cec5SDimitry Andric}
18070b57cec5SDimitry Andric
1808e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1809e8d8bef9SDimitry Andric
18100b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
1811*cb14a3feSDimitry Andricclass _LIBCPP_HIDDEN __async_func {
18120b57cec5SDimitry Andric  tuple<_Fp, _Args...> __f_;
18130b57cec5SDimitry Andric
18140b57cec5SDimitry Andricpublic:
18150b57cec5SDimitry Andric  typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
18160b57cec5SDimitry Andric
1817*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_func(_Fp&& __f, _Args&&... __args)
18185f757f3fSDimitry Andric      : __f_(std::move(__f), std::move(__args)...) {}
18190b57cec5SDimitry Andric
1820*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __async_func(__async_func&& __f) : __f_(std::move(__f.__f_)) {}
18210b57cec5SDimitry Andric
1822*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp operator()() {
18230b57cec5SDimitry Andric    typedef typename __make_tuple_indices<1 + sizeof...(_Args), 1>::type _Index;
18240b57cec5SDimitry Andric    return __execute(_Index());
18250b57cec5SDimitry Andric  }
1826*cb14a3feSDimitry Andric
18270b57cec5SDimitry Andricprivate:
18280b57cec5SDimitry Andric  template <size_t... _Indices>
1829*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp __execute(__tuple_indices<_Indices...>) {
18305f757f3fSDimitry Andric    return std::__invoke(std::move(std::get<0>(__f_)), std::move(std::get<_Indices>(__f_))...);
18310b57cec5SDimitry Andric  }
18320b57cec5SDimitry Andric};
18330b57cec5SDimitry Andric
1834*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool __does_policy_contain(launch __policy, launch __value) {
1835*cb14a3feSDimitry Andric  return (int(__policy) & int(__value)) != 0;
1836*cb14a3feSDimitry Andric}
18370b57cec5SDimitry Andric
18380b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
1839bdd1243dSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
184006c3fb27SDimitry Andric    future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
1841*cb14a3feSDimitry Andric    async(launch __policy, _Fp&& __f, _Args&&... __args) {
184206c3fb27SDimitry Andric  typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF;
18430b57cec5SDimitry Andric  typedef typename _BF::_Rp _Rp;
18440b57cec5SDimitry Andric
184506c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1846*cb14a3feSDimitry Andric  try {
18470b57cec5SDimitry Andric#  endif
18480b57cec5SDimitry Andric    if (__does_policy_contain(__policy, launch::async))
1849*cb14a3feSDimitry Andric      return std::__make_async_assoc_state<_Rp>(
1850*cb14a3feSDimitry Andric          _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...));
185106c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1852*cb14a3feSDimitry Andric  } catch (...) {
1853*cb14a3feSDimitry Andric    if (__policy == launch::async)
1854*cb14a3feSDimitry Andric      throw;
18550b57cec5SDimitry Andric  }
18560b57cec5SDimitry Andric#  endif
18570b57cec5SDimitry Andric
18580b57cec5SDimitry Andric  if (__does_policy_contain(__policy, launch::deferred))
1859*cb14a3feSDimitry Andric    return std::__make_deferred_assoc_state<_Rp>(
1860*cb14a3feSDimitry Andric        _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...));
18610b57cec5SDimitry Andric  return future<_Rp>{};
18620b57cec5SDimitry Andric}
18630b57cec5SDimitry Andric
18640b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
18655f757f3fSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
186606c3fb27SDimitry Andric    future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
1867*cb14a3feSDimitry Andric    async(_Fp&& __f, _Args&&... __args) {
1868*cb14a3feSDimitry Andric  return std::async(launch::any, std::forward<_Fp>(__f), std::forward<_Args>(__args)...);
18690b57cec5SDimitry Andric}
18700b57cec5SDimitry Andric
1871e8d8bef9SDimitry Andric#endif // C++03
18720b57cec5SDimitry Andric
18730b57cec5SDimitry Andric// shared_future
18740b57cec5SDimitry Andric
18750b57cec5SDimitry Andrictemplate <class _Rp>
1876*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future {
18770b57cec5SDimitry Andric  __assoc_state<_Rp>* __state_;
18780b57cec5SDimitry Andric
18790b57cec5SDimitry Andricpublic:
1880*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1881*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1882*cb14a3feSDimitry Andric    if (__state_)
1883*cb14a3feSDimitry Andric      __state_->__add_shared();
1884*cb14a3feSDimitry Andric  }
1885*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1886*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1887*cb14a3feSDimitry Andric    __rhs.__state_ = nullptr;
1888*cb14a3feSDimitry Andric  }
188906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~shared_future();
189006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
1891*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT {
18925f757f3fSDimitry Andric    shared_future(std::move(__rhs)).swap(*this);
18930b57cec5SDimitry Andric    return *this;
18940b57cec5SDimitry Andric  }
18950b57cec5SDimitry Andric
18960b57cec5SDimitry Andric  // retrieving the value
1897*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const _Rp& get() const { return __state_->copy(); }
18980b57cec5SDimitry Andric
1899*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
19000b57cec5SDimitry Andric
19010b57cec5SDimitry Andric  // functions to check state
1902*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
19030b57cec5SDimitry Andric
1904*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
19050b57cec5SDimitry Andric  template <class _Rep, class _Period>
1906*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1907*cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1908*cb14a3feSDimitry Andric  }
19090b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1910*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1911*cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1912*cb14a3feSDimitry Andric  }
19130b57cec5SDimitry Andric};
19140b57cec5SDimitry Andric
19150b57cec5SDimitry Andrictemplate <class _Rp>
1916*cb14a3feSDimitry Andricshared_future<_Rp>::~shared_future() {
19170b57cec5SDimitry Andric  if (__state_)
19180b57cec5SDimitry Andric    __state_->__release_shared();
19190b57cec5SDimitry Andric}
19200b57cec5SDimitry Andric
19210b57cec5SDimitry Andrictemplate <class _Rp>
1922*cb14a3feSDimitry Andricshared_future<_Rp>& shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT {
19230b57cec5SDimitry Andric  if (__rhs.__state_)
19240b57cec5SDimitry Andric    __rhs.__state_->__add_shared();
19250b57cec5SDimitry Andric  if (__state_)
19260b57cec5SDimitry Andric    __state_->__release_shared();
19270b57cec5SDimitry Andric  __state_ = __rhs.__state_;
19280b57cec5SDimitry Andric  return *this;
19290b57cec5SDimitry Andric}
19300b57cec5SDimitry Andric
19310b57cec5SDimitry Andrictemplate <class _Rp>
1932*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&> {
19330b57cec5SDimitry Andric  __assoc_state<_Rp&>* __state_;
19340b57cec5SDimitry Andric
19350b57cec5SDimitry Andricpublic:
1936*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1937*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {
1938*cb14a3feSDimitry Andric    if (__state_)
1939*cb14a3feSDimitry Andric      __state_->__add_shared();
1940*cb14a3feSDimitry Andric  }
1941*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1942*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1943*cb14a3feSDimitry Andric    __rhs.__state_ = nullptr;
1944*cb14a3feSDimitry Andric  }
194506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~shared_future();
194606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs);
1947*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT {
19485f757f3fSDimitry Andric    shared_future(std::move(__rhs)).swap(*this);
19490b57cec5SDimitry Andric    return *this;
19500b57cec5SDimitry Andric  }
19510b57cec5SDimitry Andric
19520b57cec5SDimitry Andric  // retrieving the value
1953*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& get() const { return __state_->copy(); }
19540b57cec5SDimitry Andric
1955*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
19560b57cec5SDimitry Andric
19570b57cec5SDimitry Andric  // functions to check state
1958*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
19590b57cec5SDimitry Andric
1960*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
19610b57cec5SDimitry Andric  template <class _Rep, class _Period>
1962*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1963*cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1964*cb14a3feSDimitry Andric  }
19650b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1966*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1967*cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1968*cb14a3feSDimitry Andric  }
19690b57cec5SDimitry Andric};
19700b57cec5SDimitry Andric
19710b57cec5SDimitry Andrictemplate <class _Rp>
1972*cb14a3feSDimitry Andricshared_future<_Rp&>::~shared_future() {
19730b57cec5SDimitry Andric  if (__state_)
19740b57cec5SDimitry Andric    __state_->__release_shared();
19750b57cec5SDimitry Andric}
19760b57cec5SDimitry Andric
19770b57cec5SDimitry Andrictemplate <class _Rp>
1978*cb14a3feSDimitry Andricshared_future<_Rp&>& shared_future<_Rp&>::operator=(const shared_future& __rhs) {
19790b57cec5SDimitry Andric  if (__rhs.__state_)
19800b57cec5SDimitry Andric    __rhs.__state_->__add_shared();
19810b57cec5SDimitry Andric  if (__state_)
19820b57cec5SDimitry Andric    __state_->__release_shared();
19830b57cec5SDimitry Andric  __state_ = __rhs.__state_;
19840b57cec5SDimitry Andric  return *this;
19850b57cec5SDimitry Andric}
19860b57cec5SDimitry Andric
19870b57cec5SDimitry Andrictemplate <>
1988*cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI shared_future<void> {
19890b57cec5SDimitry Andric  __assoc_sub_state* __state_;
19900b57cec5SDimitry Andric
19910b57cec5SDimitry Andricpublic:
1992*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1993*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {
1994*cb14a3feSDimitry Andric    if (__state_)
1995*cb14a3feSDimitry Andric      __state_->__add_shared();
1996*cb14a3feSDimitry Andric  }
1997*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1998*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1999*cb14a3feSDimitry Andric    __rhs.__state_ = nullptr;
2000*cb14a3feSDimitry Andric  }
20010b57cec5SDimitry Andric  ~shared_future();
20020b57cec5SDimitry Andric  shared_future& operator=(const shared_future& __rhs);
2003*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT {
20045f757f3fSDimitry Andric    shared_future(std::move(__rhs)).swap(*this);
20050b57cec5SDimitry Andric    return *this;
20060b57cec5SDimitry Andric  }
20070b57cec5SDimitry Andric
20080b57cec5SDimitry Andric  // retrieving the value
2009*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void get() const { __state_->copy(); }
20100b57cec5SDimitry Andric
2011*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
20120b57cec5SDimitry Andric
20130b57cec5SDimitry Andric  // functions to check state
2014*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
20150b57cec5SDimitry Andric
2016*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
20170b57cec5SDimitry Andric  template <class _Rep, class _Period>
2018*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
2019*cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
2020*cb14a3feSDimitry Andric  }
20210b57cec5SDimitry Andric  template <class _Clock, class _Duration>
2022*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
2023*cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
2024*cb14a3feSDimitry Andric  }
20250b57cec5SDimitry Andric};
20260b57cec5SDimitry Andric
20270b57cec5SDimitry Andrictemplate <class _Rp>
2028*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT {
20290b57cec5SDimitry Andric  __x.swap(__y);
20300b57cec5SDimitry Andric}
20310b57cec5SDimitry Andric
20320b57cec5SDimitry Andrictemplate <class _Rp>
2033*cb14a3feSDimitry Andricinline shared_future<_Rp> future<_Rp>::share() _NOEXCEPT {
20345f757f3fSDimitry Andric  return shared_future<_Rp>(std::move(*this));
20350b57cec5SDimitry Andric}
20360b57cec5SDimitry Andric
20370b57cec5SDimitry Andrictemplate <class _Rp>
2038*cb14a3feSDimitry Andricinline shared_future<_Rp&> future<_Rp&>::share() _NOEXCEPT {
20395f757f3fSDimitry Andric  return shared_future<_Rp&>(std::move(*this));
20400b57cec5SDimitry Andric}
20410b57cec5SDimitry Andric
2042*cb14a3feSDimitry Andricinline shared_future<void> future<void>::share() _NOEXCEPT { return shared_future<void>(std::move(*this)); }
20430b57cec5SDimitry Andric
20440b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
20450b57cec5SDimitry Andric
2046bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
2047bdd1243dSDimitry Andric#  include <chrono>
2048bdd1243dSDimitry Andric#endif
2049bdd1243dSDimitry Andric
205006c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
205106c3fb27SDimitry Andric#  include <atomic>
205206c3fb27SDimitry Andric#  include <cstdlib>
205306c3fb27SDimitry Andric#  include <exception>
20545f757f3fSDimitry Andric#  include <iosfwd>
205506c3fb27SDimitry Andric#  include <system_error>
205606c3fb27SDimitry Andric#endif
205706c3fb27SDimitry Andric
20580b57cec5SDimitry Andric#endif // _LIBCPP_FUTURE
2059