xref: /freebsd/contrib/llvm-project/libcxx/include/future (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_FUTURE
110b57cec5SDimitry Andric#define _LIBCPP_FUTURE
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    future synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
190b57cec5SDimitry Andricenum class future_errc
200b57cec5SDimitry Andric{
210b57cec5SDimitry Andric    future_already_retrieved = 1,
220b57cec5SDimitry Andric    promise_already_satisfied,
230b57cec5SDimitry Andric    no_state,
240b57cec5SDimitry Andric    broken_promise
250b57cec5SDimitry Andric};
260b57cec5SDimitry Andric
270b57cec5SDimitry Andricenum class launch
280b57cec5SDimitry Andric{
290b57cec5SDimitry Andric    async = 1,
300b57cec5SDimitry Andric    deferred = 2,
310b57cec5SDimitry Andric    any = async | deferred
320b57cec5SDimitry Andric};
330b57cec5SDimitry Andric
340b57cec5SDimitry Andricenum class future_status
350b57cec5SDimitry Andric{
360b57cec5SDimitry Andric    ready,
370b57cec5SDimitry Andric    timeout,
380b57cec5SDimitry Andric    deferred
390b57cec5SDimitry Andric};
400b57cec5SDimitry Andric
410b57cec5SDimitry Andrictemplate <> struct is_error_code_enum<future_errc> : public true_type { };
420b57cec5SDimitry Andricerror_code make_error_code(future_errc e) noexcept;
430b57cec5SDimitry Andricerror_condition make_error_condition(future_errc e) noexcept;
440b57cec5SDimitry Andric
450b57cec5SDimitry Andricconst error_category& future_category() noexcept;
460b57cec5SDimitry Andric
475f757f3fSDimitry Andricclass future_error : public logic_error {
480b57cec5SDimitry Andricpublic:
495f757f3fSDimitry Andric    explicit future_error(future_errc e); // since C++17
505f757f3fSDimitry Andric
510b57cec5SDimitry Andric    const error_code& code() const noexcept;
520b57cec5SDimitry Andric    const char*       what() const noexcept;
535f757f3fSDimitry Andric
545f757f3fSDimitry Andricprivate:
555f757f3fSDimitry Andric    error_code ec_;             // exposition only
560b57cec5SDimitry Andric};
570b57cec5SDimitry Andric
580b57cec5SDimitry Andrictemplate <class R>
590b57cec5SDimitry Andricclass promise
600b57cec5SDimitry Andric{
610b57cec5SDimitry Andricpublic:
620b57cec5SDimitry Andric    promise();
630b57cec5SDimitry Andric    template <class Allocator>
640b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
650b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
660b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
670b57cec5SDimitry Andric    ~promise();
680b57cec5SDimitry Andric
690b57cec5SDimitry Andric    // assignment
700b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
710b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
720b57cec5SDimitry Andric    void swap(promise& other) noexcept;
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric    // retrieving the result
750b57cec5SDimitry Andric    future<R> get_future();
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric    // setting the result
780b57cec5SDimitry Andric    void set_value(const R& r);
790b57cec5SDimitry Andric    void set_value(R&& r);
800b57cec5SDimitry Andric    void set_exception(exception_ptr p);
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric    // setting the result with deferred notification
830b57cec5SDimitry Andric    void set_value_at_thread_exit(const R& r);
840b57cec5SDimitry Andric    void set_value_at_thread_exit(R&& r);
850b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
860b57cec5SDimitry Andric};
870b57cec5SDimitry Andric
880b57cec5SDimitry Andrictemplate <class R>
890b57cec5SDimitry Andricclass promise<R&>
900b57cec5SDimitry Andric{
910b57cec5SDimitry Andricpublic:
920b57cec5SDimitry Andric    promise();
930b57cec5SDimitry Andric    template <class Allocator>
940b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
950b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
960b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
970b57cec5SDimitry Andric    ~promise();
980b57cec5SDimitry Andric
990b57cec5SDimitry Andric    // assignment
1000b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
1010b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
1020b57cec5SDimitry Andric    void swap(promise& other) noexcept;
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andric    // retrieving the result
1050b57cec5SDimitry Andric    future<R&> get_future();
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric    // setting the result
1080b57cec5SDimitry Andric    void set_value(R& r);
1090b57cec5SDimitry Andric    void set_exception(exception_ptr p);
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andric    // setting the result with deferred notification
1120b57cec5SDimitry Andric    void set_value_at_thread_exit(R&);
1130b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
1140b57cec5SDimitry Andric};
1150b57cec5SDimitry Andric
1160b57cec5SDimitry Andrictemplate <>
1170b57cec5SDimitry Andricclass promise<void>
1180b57cec5SDimitry Andric{
1190b57cec5SDimitry Andricpublic:
1200b57cec5SDimitry Andric    promise();
1210b57cec5SDimitry Andric    template <class Allocator>
1220b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
1230b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
1240b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
1250b57cec5SDimitry Andric    ~promise();
1260b57cec5SDimitry Andric
1270b57cec5SDimitry Andric    // assignment
1280b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
1290b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
1300b57cec5SDimitry Andric    void swap(promise& other) noexcept;
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric    // retrieving the result
1330b57cec5SDimitry Andric    future<void> get_future();
1340b57cec5SDimitry Andric
1350b57cec5SDimitry Andric    // setting the result
1360b57cec5SDimitry Andric    void set_value();
1370b57cec5SDimitry Andric    void set_exception(exception_ptr p);
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andric    // setting the result with deferred notification
1400b57cec5SDimitry Andric    void set_value_at_thread_exit();
1410b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
1420b57cec5SDimitry Andric};
1430b57cec5SDimitry Andric
1440b57cec5SDimitry Andrictemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andrictemplate <class R, class Alloc>
1470b57cec5SDimitry Andric    struct uses_allocator<promise<R>, Alloc> : public true_type {};
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andrictemplate <class R>
1500b57cec5SDimitry Andricclass future
1510b57cec5SDimitry Andric{
1520b57cec5SDimitry Andricpublic:
1530b57cec5SDimitry Andric    future() noexcept;
1540b57cec5SDimitry Andric    future(future&&) noexcept;
1550b57cec5SDimitry Andric    future(const future& rhs) = delete;
1560b57cec5SDimitry Andric    ~future();
1570b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
1580b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
1590b57cec5SDimitry Andric    shared_future<R> share() noexcept;
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric    // retrieving the value
1620b57cec5SDimitry Andric    R get();
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric    // functions to check state
1650b57cec5SDimitry Andric    bool valid() const noexcept;
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andric    void wait() const;
1680b57cec5SDimitry Andric    template <class Rep, class Period>
1690b57cec5SDimitry Andric        future_status
1700b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
1710b57cec5SDimitry Andric    template <class Clock, class Duration>
1720b57cec5SDimitry Andric        future_status
1730b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
1740b57cec5SDimitry Andric};
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andrictemplate <class R>
1770b57cec5SDimitry Andricclass future<R&>
1780b57cec5SDimitry Andric{
1790b57cec5SDimitry Andricpublic:
1800b57cec5SDimitry Andric    future() noexcept;
1810b57cec5SDimitry Andric    future(future&&) noexcept;
1820b57cec5SDimitry Andric    future(const future& rhs) = delete;
1830b57cec5SDimitry Andric    ~future();
1840b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
1850b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
1860b57cec5SDimitry Andric    shared_future<R&> share() noexcept;
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andric    // retrieving the value
1890b57cec5SDimitry Andric    R& get();
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andric    // functions to check state
1920b57cec5SDimitry Andric    bool valid() const noexcept;
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric    void wait() const;
1950b57cec5SDimitry Andric    template <class Rep, class Period>
1960b57cec5SDimitry Andric        future_status
1970b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
1980b57cec5SDimitry Andric    template <class Clock, class Duration>
1990b57cec5SDimitry Andric        future_status
2000b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2010b57cec5SDimitry Andric};
2020b57cec5SDimitry Andric
2030b57cec5SDimitry Andrictemplate <>
2040b57cec5SDimitry Andricclass future<void>
2050b57cec5SDimitry Andric{
2060b57cec5SDimitry Andricpublic:
2070b57cec5SDimitry Andric    future() noexcept;
2080b57cec5SDimitry Andric    future(future&&) noexcept;
2090b57cec5SDimitry Andric    future(const future& rhs) = delete;
2100b57cec5SDimitry Andric    ~future();
2110b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
2120b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
2130b57cec5SDimitry Andric    shared_future<void> share() noexcept;
2140b57cec5SDimitry Andric
2150b57cec5SDimitry Andric    // retrieving the value
2160b57cec5SDimitry Andric    void get();
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric    // functions to check state
2190b57cec5SDimitry Andric    bool valid() const noexcept;
2200b57cec5SDimitry Andric
2210b57cec5SDimitry Andric    void wait() const;
2220b57cec5SDimitry Andric    template <class Rep, class Period>
2230b57cec5SDimitry Andric        future_status
2240b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2250b57cec5SDimitry Andric    template <class Clock, class Duration>
2260b57cec5SDimitry Andric        future_status
2270b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2280b57cec5SDimitry Andric};
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andrictemplate <class R>
2310b57cec5SDimitry Andricclass shared_future
2320b57cec5SDimitry Andric{
2330b57cec5SDimitry Andricpublic:
2340b57cec5SDimitry Andric    shared_future() noexcept;
2350b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2360b57cec5SDimitry Andric    shared_future(future<R>&&) noexcept;
2370b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2380b57cec5SDimitry Andric    ~shared_future();
2390b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2400b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andric    // retrieving the value
2430b57cec5SDimitry Andric    const R& get() const;
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric    // functions to check state
2460b57cec5SDimitry Andric    bool valid() const noexcept;
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andric    void wait() const;
2490b57cec5SDimitry Andric    template <class Rep, class Period>
2500b57cec5SDimitry Andric        future_status
2510b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2520b57cec5SDimitry Andric    template <class Clock, class Duration>
2530b57cec5SDimitry Andric        future_status
2540b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2550b57cec5SDimitry Andric};
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andrictemplate <class R>
2580b57cec5SDimitry Andricclass shared_future<R&>
2590b57cec5SDimitry Andric{
2600b57cec5SDimitry Andricpublic:
2610b57cec5SDimitry Andric    shared_future() noexcept;
2620b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2630b57cec5SDimitry Andric    shared_future(future<R&>&&) noexcept;
2640b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2650b57cec5SDimitry Andric    ~shared_future();
2660b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2670b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric    // retrieving the value
2700b57cec5SDimitry Andric    R& get() const;
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andric    // functions to check state
2730b57cec5SDimitry Andric    bool valid() const noexcept;
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andric    void wait() const;
2760b57cec5SDimitry Andric    template <class Rep, class Period>
2770b57cec5SDimitry Andric        future_status
2780b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2790b57cec5SDimitry Andric    template <class Clock, class Duration>
2800b57cec5SDimitry Andric        future_status
2810b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2820b57cec5SDimitry Andric};
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andrictemplate <>
2850b57cec5SDimitry Andricclass shared_future<void>
2860b57cec5SDimitry Andric{
2870b57cec5SDimitry Andricpublic:
2880b57cec5SDimitry Andric    shared_future() noexcept;
2890b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2900b57cec5SDimitry Andric    shared_future(future<void>&&) noexcept;
2910b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2920b57cec5SDimitry Andric    ~shared_future();
2930b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2940b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andric    // retrieving the value
2970b57cec5SDimitry Andric    void get() const;
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric    // functions to check state
3000b57cec5SDimitry Andric    bool valid() const noexcept;
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andric    void wait() const;
3030b57cec5SDimitry Andric    template <class Rep, class Period>
3040b57cec5SDimitry Andric        future_status
3050b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
3060b57cec5SDimitry Andric    template <class Clock, class Duration>
3070b57cec5SDimitry Andric        future_status
3080b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
3090b57cec5SDimitry Andric};
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andrictemplate <class F, class... Args>
3120b57cec5SDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
3130b57cec5SDimitry Andric  async(F&& f, Args&&... args);
3140b57cec5SDimitry Andric
3150b57cec5SDimitry Andrictemplate <class F, class... Args>
3160b57cec5SDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
3170b57cec5SDimitry Andric  async(launch policy, F&& f, Args&&... args);
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andrictemplate <class> class packaged_task; // undefined
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andrictemplate <class R, class... ArgTypes>
3220b57cec5SDimitry Andricclass packaged_task<R(ArgTypes...)>
3230b57cec5SDimitry Andric{
3240b57cec5SDimitry Andricpublic:
3250b57cec5SDimitry Andric    typedef R result_type; // extension
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric    // construction and destruction
3280b57cec5SDimitry Andric    packaged_task() noexcept;
3290b57cec5SDimitry Andric    template <class F>
3300b57cec5SDimitry Andric        explicit packaged_task(F&& f);
3310b57cec5SDimitry Andric    template <class F, class Allocator>
3320b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const Allocator& a, F&& f);
3330b57cec5SDimitry Andric    ~packaged_task();
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric    // no copy
3360b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
3370b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andric    // move support
3400b57cec5SDimitry Andric    packaged_task(packaged_task&& other) noexcept;
3410b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& other) noexcept;
3420b57cec5SDimitry Andric    void swap(packaged_task& other) noexcept;
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andric    bool valid() const noexcept;
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andric    // result retrieval
3470b57cec5SDimitry Andric    future<R> get_future();
3480b57cec5SDimitry Andric
3490b57cec5SDimitry Andric    // execution
3500b57cec5SDimitry Andric    void operator()(ArgTypes... );
3510b57cec5SDimitry Andric    void make_ready_at_thread_exit(ArgTypes...);
3520b57cec5SDimitry Andric
3530b57cec5SDimitry Andric    void reset();
3540b57cec5SDimitry Andric};
3550b57cec5SDimitry Andric
3560b57cec5SDimitry Andrictemplate <class R>
3570b57cec5SDimitry Andric  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andrictemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
3600b57cec5SDimitry Andric
3610b57cec5SDimitry Andric}  // std
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andric*/
3640b57cec5SDimitry Andric
3657a6dacacSDimitry Andric#include <__config>
3667a6dacacSDimitry Andric
367*0fca6ea1SDimitry Andric#if !defined(_LIBCPP_HAS_NO_THREADS)
3687a6dacacSDimitry Andric
369*0fca6ea1SDimitry Andric#  include <__assert>
37081ad6265SDimitry Andric#  include <__chrono/duration.h>
37181ad6265SDimitry Andric#  include <__chrono/time_point.h>
37206c3fb27SDimitry Andric#  include <__exception/exception_ptr.h>
37306c3fb27SDimitry Andric#  include <__memory/addressof.h>
37406c3fb27SDimitry Andric#  include <__memory/allocator.h>
375fe6060f1SDimitry Andric#  include <__memory/allocator_arg_t.h>
376bdd1243dSDimitry Andric#  include <__memory/allocator_destructor.h>
37706c3fb27SDimitry Andric#  include <__memory/allocator_traits.h>
37806c3fb27SDimitry Andric#  include <__memory/compressed_pair.h>
37906c3fb27SDimitry Andric#  include <__memory/pointer_traits.h>
38006c3fb27SDimitry Andric#  include <__memory/shared_ptr.h>
38106c3fb27SDimitry Andric#  include <__memory/unique_ptr.h>
382fe6060f1SDimitry Andric#  include <__memory/uses_allocator.h>
38306c3fb27SDimitry Andric#  include <__system_error/error_category.h>
38406c3fb27SDimitry Andric#  include <__system_error/error_code.h>
38506c3fb27SDimitry Andric#  include <__system_error/error_condition.h>
38606c3fb27SDimitry Andric#  include <__type_traits/aligned_storage.h>
387bdd1243dSDimitry Andric#  include <__type_traits/strip_signature.h>
3880eae32dcSDimitry Andric#  include <__utility/auto_cast.h>
389fe6060f1SDimitry Andric#  include <__utility/forward.h>
39081ad6265SDimitry Andric#  include <__utility/move.h>
3910b57cec5SDimitry Andric#  include <mutex>
392bdd1243dSDimitry Andric#  include <new>
39306c3fb27SDimitry Andric#  include <stdexcept>
3940b57cec5SDimitry Andric#  include <thread>
39504eeddc0SDimitry Andric#  include <version>
3960b57cec5SDimitry Andric
3970b57cec5SDimitry Andric#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3980b57cec5SDimitry Andric#    pragma GCC system_header
3990b57cec5SDimitry Andric#  endif
4000b57cec5SDimitry Andric
401b3edf446SDimitry Andric_LIBCPP_PUSH_MACROS
402b3edf446SDimitry Andric#  include <__undef_macros>
403b3edf446SDimitry Andric
4040b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
4050b57cec5SDimitry Andric
4060b57cec5SDimitry Andric// enum class future_errc
407cb14a3feSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_errc){
408cb14a3feSDimitry Andric    future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise};
4090b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andrictemplate <>
4120b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
4130b57cec5SDimitry Andric
41481ad6265SDimitry Andric#  ifdef _LIBCPP_CXX03_LANG
4150b57cec5SDimitry Andrictemplate <>
4160b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type {};
4170b57cec5SDimitry Andric#  endif
4180b57cec5SDimitry Andric
4190b57cec5SDimitry Andric// enum class launch
420cb14a3feSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(launch){async = 1, deferred = 2, any = async | deferred};
4210b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
4220b57cec5SDimitry Andric
42381ad6265SDimitry Andric#  ifndef _LIBCPP_CXX03_LANG
4240b57cec5SDimitry Andric
4250b57cec5SDimitry Andrictypedef underlying_type<launch>::type __launch_underlying_type;
4260b57cec5SDimitry Andric
427*0fca6ea1SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr launch operator&(launch __x, launch __y) {
428cb14a3feSDimitry Andric  return static_cast<launch>(static_cast<__launch_underlying_type>(__x) & static_cast<__launch_underlying_type>(__y));
4290b57cec5SDimitry Andric}
4300b57cec5SDimitry Andric
431*0fca6ea1SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr launch operator|(launch __x, launch __y) {
432cb14a3feSDimitry Andric  return static_cast<launch>(static_cast<__launch_underlying_type>(__x) | static_cast<__launch_underlying_type>(__y));
4330b57cec5SDimitry Andric}
4340b57cec5SDimitry Andric
435*0fca6ea1SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr launch operator^(launch __x, launch __y) {
436cb14a3feSDimitry Andric  return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^ static_cast<__launch_underlying_type>(__y));
4370b57cec5SDimitry Andric}
4380b57cec5SDimitry Andric
439*0fca6ea1SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr launch operator~(launch __x) {
4400b57cec5SDimitry Andric  return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
4410b57cec5SDimitry Andric}
4420b57cec5SDimitry Andric
443cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI launch& operator&=(launch& __x, launch __y) {
444cb14a3feSDimitry Andric  __x = __x & __y;
445cb14a3feSDimitry Andric  return __x;
4460b57cec5SDimitry Andric}
4470b57cec5SDimitry Andric
448cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI launch& operator|=(launch& __x, launch __y) {
449cb14a3feSDimitry Andric  __x = __x | __y;
450cb14a3feSDimitry Andric  return __x;
4510b57cec5SDimitry Andric}
4520b57cec5SDimitry Andric
453cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI launch& operator^=(launch& __x, launch __y) {
454cb14a3feSDimitry Andric  __x = __x ^ __y;
455cb14a3feSDimitry Andric  return __x;
4560b57cec5SDimitry Andric}
4570b57cec5SDimitry Andric
45881ad6265SDimitry Andric#  endif // !_LIBCPP_CXX03_LANG
4590b57cec5SDimitry Andric
4600b57cec5SDimitry Andric// enum class future_status
461cb14a3feSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_status){ready, timeout, deferred};
4620b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
4630b57cec5SDimitry Andric
46406c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;
4650b57cec5SDimitry Andric
466cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(future_errc __e) _NOEXCEPT {
4670b57cec5SDimitry Andric  return error_code(static_cast<int>(__e), future_category());
4680b57cec5SDimitry Andric}
4690b57cec5SDimitry Andric
470cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(future_errc __e) _NOEXCEPT {
4710b57cec5SDimitry Andric  return error_condition(static_cast<int>(__e), future_category());
4720b57cec5SDimitry Andric}
4730b57cec5SDimitry Andric
4745f757f3fSDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_future_error(future_errc __ev);
475fe6060f1SDimitry Andric
4765f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future_error : public logic_error {
4775f757f3fSDimitry Andric  error_code __ec_;
4785f757f3fSDimitry Andric
4795f757f3fSDimitry Andric  future_error(error_code);
4805f757f3fSDimitry Andric  friend void __throw_future_error(future_errc);
481cb14a3feSDimitry Andric  template <class>
482cb14a3feSDimitry Andric  friend class promise;
4835f757f3fSDimitry Andric
4845f757f3fSDimitry Andricpublic:
4855f757f3fSDimitry Andric#  if _LIBCPP_STD_VER >= 17
4865f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit future_error(future_errc __ec) : future_error(std::make_error_code(__ec)) {}
4875f757f3fSDimitry Andric#  endif
4885f757f3fSDimitry Andric
489cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
4900b57cec5SDimitry Andric
49106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default;
492bdd1243dSDimitry Andric  ~future_error() _NOEXCEPT override;
4930b57cec5SDimitry Andric};
4940b57cec5SDimitry Andric
4955f757f3fSDimitry Andric// Declared above std::future_error
496cb14a3feSDimitry Andricvoid __throw_future_error(future_errc __ev) {
49706c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
498753f127fSDimitry Andric  throw future_error(make_error_code(__ev));
4990b57cec5SDimitry Andric#  else
50006c3fb27SDimitry Andric  (void)__ev;
50106c3fb27SDimitry Andric  _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode");
5020b57cec5SDimitry Andric#  endif
5030b57cec5SDimitry Andric}
5040b57cec5SDimitry Andric
5055f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI __assoc_sub_state : public __shared_count {
5060b57cec5SDimitry Andricprotected:
5070b57cec5SDimitry Andric  exception_ptr __exception_;
5080b57cec5SDimitry Andric  mutable mutex __mut_;
5090b57cec5SDimitry Andric  mutable condition_variable __cv_;
5100b57cec5SDimitry Andric  unsigned __state_;
5110b57cec5SDimitry Andric
512bdd1243dSDimitry Andric  void __on_zero_shared() _NOEXCEPT override;
5130b57cec5SDimitry Andric  void __sub_wait(unique_lock<mutex>& __lk);
514cb14a3feSDimitry Andric
5150b57cec5SDimitry Andricpublic:
516cb14a3feSDimitry Andric  enum { __constructed = 1, __future_attached = 2, ready = 4, deferred = 8 };
5170b57cec5SDimitry Andric
518cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __assoc_sub_state() : __state_(0) {}
5190b57cec5SDimitry Andric
520cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool __has_value() const { return (__state_ & __constructed) || (__exception_ != nullptr); }
5210b57cec5SDimitry Andric
522cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __attach_future() {
5230b57cec5SDimitry Andric    lock_guard<mutex> __lk(__mut_);
5240b57cec5SDimitry Andric    bool __has_future_attached = (__state_ & __future_attached) != 0;
5250b57cec5SDimitry Andric    if (__has_future_attached)
5260b57cec5SDimitry Andric      __throw_future_error(future_errc::future_already_retrieved);
5270b57cec5SDimitry Andric    this->__add_shared();
5280b57cec5SDimitry Andric    __state_ |= __future_attached;
5290b57cec5SDimitry Andric  }
5300b57cec5SDimitry Andric
531cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __set_deferred() { __state_ |= deferred; }
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andric  void __make_ready();
534cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool __is_ready() const { return (__state_ & ready) != 0; }
5350b57cec5SDimitry Andric
5360b57cec5SDimitry Andric  void set_value();
5370b57cec5SDimitry Andric  void set_value_at_thread_exit();
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric  void set_exception(exception_ptr __p);
5400b57cec5SDimitry Andric  void set_exception_at_thread_exit(exception_ptr __p);
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andric  void copy();
5430b57cec5SDimitry Andric
5440b57cec5SDimitry Andric  void wait();
5450b57cec5SDimitry Andric  template <class _Rep, class _Period>
546cb14a3feSDimitry Andric  future_status _LIBCPP_HIDE_FROM_ABI wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
5470b57cec5SDimitry Andric  template <class _Clock, class _Duration>
548cb14a3feSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS future_status
5490b57cec5SDimitry Andric  wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
5500b57cec5SDimitry Andric
5510b57cec5SDimitry Andric  virtual void __execute();
5520b57cec5SDimitry Andric};
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andrictemplate <class _Clock, class _Duration>
555cb14a3feSDimitry Andricfuture_status __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
5560b57cec5SDimitry Andric  unique_lock<mutex> __lk(__mut_);
5570b57cec5SDimitry Andric  if (__state_ & deferred)
5580b57cec5SDimitry Andric    return future_status::deferred;
5590b57cec5SDimitry Andric  while (!(__state_ & ready) && _Clock::now() < __abs_time)
5600b57cec5SDimitry Andric    __cv_.wait_until(__lk, __abs_time);
5610b57cec5SDimitry Andric  if (__state_ & ready)
5620b57cec5SDimitry Andric    return future_status::ready;
5630b57cec5SDimitry Andric  return future_status::timeout;
5640b57cec5SDimitry Andric}
5650b57cec5SDimitry Andric
5660b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
567cb14a3feSDimitry Andricinline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
5680b57cec5SDimitry Andric  return wait_until(chrono::steady_clock::now() + __rel_time);
5690b57cec5SDimitry Andric}
5700b57cec5SDimitry Andric
5710b57cec5SDimitry Andrictemplate <class _Rp>
572cb14a3feSDimitry Andricclass _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state {
5730b57cec5SDimitry Andric  typedef __assoc_sub_state base;
574bdd1243dSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
5755f757f3fSDimitry Andric  typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up;
576bdd1243dSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_POP
577cb14a3feSDimitry Andric
5780b57cec5SDimitry Andricprotected:
5790b57cec5SDimitry Andric  _Up __value_;
5800b57cec5SDimitry Andric
58106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
5820b57cec5SDimitry Andric
583cb14a3feSDimitry Andricpublic:
5840b57cec5SDimitry Andric  template <class _Arg>
58506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg);
5860b57cec5SDimitry Andric
5870b57cec5SDimitry Andric  template <class _Arg>
58806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg);
5890b57cec5SDimitry Andric
59006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp move();
59106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy();
5920b57cec5SDimitry Andric};
5930b57cec5SDimitry Andric
5940b57cec5SDimitry Andrictemplate <class _Rp>
595cb14a3feSDimitry Andricvoid __assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT {
5960b57cec5SDimitry Andric  if (this->__state_ & base::__constructed)
5970b57cec5SDimitry Andric    reinterpret_cast<_Rp*>(&__value_)->~_Rp();
5980b57cec5SDimitry Andric  delete this;
5990b57cec5SDimitry Andric}
6000b57cec5SDimitry Andric
6010b57cec5SDimitry Andrictemplate <class _Rp>
6020b57cec5SDimitry Andrictemplate <class _Arg>
603cb14a3feSDimitry Andricvoid __assoc_state<_Rp>::set_value(_Arg&& __arg) {
6040b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6050b57cec5SDimitry Andric  if (this->__has_value())
6060b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6075f757f3fSDimitry Andric  ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
6080b57cec5SDimitry Andric  this->__state_ |= base::__constructed | base::ready;
6090b57cec5SDimitry Andric  __cv_.notify_all();
6100b57cec5SDimitry Andric}
6110b57cec5SDimitry Andric
6120b57cec5SDimitry Andrictemplate <class _Rp>
6130b57cec5SDimitry Andrictemplate <class _Arg>
614cb14a3feSDimitry Andricvoid __assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) {
6150b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6160b57cec5SDimitry Andric  if (this->__has_value())
6170b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6185f757f3fSDimitry Andric  ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
6190b57cec5SDimitry Andric  this->__state_ |= base::__constructed;
6200b57cec5SDimitry Andric  __thread_local_data()->__make_ready_at_thread_exit(this);
6210b57cec5SDimitry Andric}
6220b57cec5SDimitry Andric
6230b57cec5SDimitry Andrictemplate <class _Rp>
624cb14a3feSDimitry Andric_Rp __assoc_state<_Rp>::move() {
6250b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6260b57cec5SDimitry Andric  this->__sub_wait(__lk);
6270b57cec5SDimitry Andric  if (this->__exception_ != nullptr)
628bdd1243dSDimitry Andric    std::rethrow_exception(this->__exception_);
6295f757f3fSDimitry Andric  return std::move(*reinterpret_cast<_Rp*>(&__value_));
6300b57cec5SDimitry Andric}
6310b57cec5SDimitry Andric
6320b57cec5SDimitry Andrictemplate <class _Rp>
633cb14a3feSDimitry Andric__add_lvalue_reference_t<_Rp> __assoc_state<_Rp>::copy() {
6340b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6350b57cec5SDimitry Andric  this->__sub_wait(__lk);
6360b57cec5SDimitry Andric  if (this->__exception_ != nullptr)
637bdd1243dSDimitry Andric    std::rethrow_exception(this->__exception_);
6380b57cec5SDimitry Andric  return *reinterpret_cast<_Rp*>(&__value_);
6390b57cec5SDimitry Andric}
6400b57cec5SDimitry Andric
6410b57cec5SDimitry Andrictemplate <class _Rp>
642cb14a3feSDimitry Andricclass __assoc_state<_Rp&> : public __assoc_sub_state {
6430b57cec5SDimitry Andric  typedef __assoc_sub_state base;
6440b57cec5SDimitry Andric  typedef _Rp* _Up;
645cb14a3feSDimitry Andric
6460b57cec5SDimitry Andricprotected:
6470b57cec5SDimitry Andric  _Up __value_;
6480b57cec5SDimitry Andric
64906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
6500b57cec5SDimitry Andric
651cb14a3feSDimitry Andricpublic:
65206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg);
65306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg);
6540b57cec5SDimitry Andric
65506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& copy();
6560b57cec5SDimitry Andric};
6570b57cec5SDimitry Andric
6580b57cec5SDimitry Andrictemplate <class _Rp>
659cb14a3feSDimitry Andricvoid __assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT {
6600b57cec5SDimitry Andric  delete this;
6610b57cec5SDimitry Andric}
6620b57cec5SDimitry Andric
6630b57cec5SDimitry Andrictemplate <class _Rp>
664cb14a3feSDimitry Andricvoid __assoc_state<_Rp&>::set_value(_Rp& __arg) {
6650b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6660b57cec5SDimitry Andric  if (this->__has_value())
6670b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6685f757f3fSDimitry Andric  __value_ = std::addressof(__arg);
6690b57cec5SDimitry Andric  this->__state_ |= base::__constructed | base::ready;
6700b57cec5SDimitry Andric  __cv_.notify_all();
6710b57cec5SDimitry Andric}
6720b57cec5SDimitry Andric
6730b57cec5SDimitry Andrictemplate <class _Rp>
674cb14a3feSDimitry Andricvoid __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) {
6750b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6760b57cec5SDimitry Andric  if (this->__has_value())
6770b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
6785f757f3fSDimitry Andric  __value_ = std::addressof(__arg);
6790b57cec5SDimitry Andric  this->__state_ |= base::__constructed;
6800b57cec5SDimitry Andric  __thread_local_data()->__make_ready_at_thread_exit(this);
6810b57cec5SDimitry Andric}
6820b57cec5SDimitry Andric
6830b57cec5SDimitry Andrictemplate <class _Rp>
684cb14a3feSDimitry Andric_Rp& __assoc_state<_Rp&>::copy() {
6850b57cec5SDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
6860b57cec5SDimitry Andric  this->__sub_wait(__lk);
6870b57cec5SDimitry Andric  if (this->__exception_ != nullptr)
688bdd1243dSDimitry Andric    std::rethrow_exception(this->__exception_);
6890b57cec5SDimitry Andric  return *__value_;
6900b57cec5SDimitry Andric}
6910b57cec5SDimitry Andric
6920b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
693cb14a3feSDimitry Andricclass __assoc_state_alloc : public __assoc_state<_Rp> {
6940b57cec5SDimitry Andric  typedef __assoc_state<_Rp> base;
6950b57cec5SDimitry Andric  _Alloc __alloc_;
6960b57cec5SDimitry Andric
69706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
698cb14a3feSDimitry Andric
6990b57cec5SDimitry Andricpublic:
700cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
7010b57cec5SDimitry Andric};
7020b57cec5SDimitry Andric
7030b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
704cb14a3feSDimitry Andricvoid __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT {
7050b57cec5SDimitry Andric  if (this->__state_ & base::__constructed)
7065f757f3fSDimitry Andric    reinterpret_cast<_Rp*>(std::addressof(this->__value_))->~_Rp();
7070b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
7080b57cec5SDimitry Andric  typedef allocator_traits<_Al> _ATraits;
7090b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7100b57cec5SDimitry Andric  _Al __a(__alloc_);
7110b57cec5SDimitry Andric  this->~__assoc_state_alloc();
7120b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
7130b57cec5SDimitry Andric}
7140b57cec5SDimitry Andric
7150b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
716cb14a3feSDimitry Andricclass __assoc_state_alloc<_Rp&, _Alloc> : public __assoc_state<_Rp&> {
7170b57cec5SDimitry Andric  typedef __assoc_state<_Rp&> base;
7180b57cec5SDimitry Andric  _Alloc __alloc_;
7190b57cec5SDimitry Andric
72006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
721cb14a3feSDimitry Andric
7220b57cec5SDimitry Andricpublic:
723cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
7240b57cec5SDimitry Andric};
7250b57cec5SDimitry Andric
7260b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
727cb14a3feSDimitry Andricvoid __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT {
7280b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
7290b57cec5SDimitry Andric  typedef allocator_traits<_Al> _ATraits;
7300b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7310b57cec5SDimitry Andric  _Al __a(__alloc_);
7320b57cec5SDimitry Andric  this->~__assoc_state_alloc();
7330b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
7340b57cec5SDimitry Andric}
7350b57cec5SDimitry Andric
7360b57cec5SDimitry Andrictemplate <class _Alloc>
737cb14a3feSDimitry Andricclass __assoc_sub_state_alloc : public __assoc_sub_state {
7380b57cec5SDimitry Andric  typedef __assoc_sub_state base;
7390b57cec5SDimitry Andric  _Alloc __alloc_;
7400b57cec5SDimitry Andric
74106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
742cb14a3feSDimitry Andric
7430b57cec5SDimitry Andricpublic:
744cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_sub_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
7450b57cec5SDimitry Andric};
7460b57cec5SDimitry Andric
7470b57cec5SDimitry Andrictemplate <class _Alloc>
748cb14a3feSDimitry Andricvoid __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT {
7490b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
7500b57cec5SDimitry Andric  typedef allocator_traits<_Al> _ATraits;
7510b57cec5SDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7520b57cec5SDimitry Andric  _Al __a(__alloc_);
7530b57cec5SDimitry Andric  this->~__assoc_sub_state_alloc();
7540b57cec5SDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
7550b57cec5SDimitry Andric}
7560b57cec5SDimitry Andric
7570b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
758cb14a3feSDimitry Andricclass __deferred_assoc_state : public __assoc_state<_Rp> {
7590b57cec5SDimitry Andric  typedef __assoc_state<_Rp> base;
7600b57cec5SDimitry Andric
7610b57cec5SDimitry Andric  _Fp __func_;
7620b57cec5SDimitry Andric
7630b57cec5SDimitry Andricpublic:
764cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f);
7650b57cec5SDimitry Andric
76606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
7670b57cec5SDimitry Andric};
7680b57cec5SDimitry Andric
7690b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
770cb14a3feSDimitry Andricinline __deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {
7710b57cec5SDimitry Andric  this->__set_deferred();
7720b57cec5SDimitry Andric}
7730b57cec5SDimitry Andric
7740b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
775cb14a3feSDimitry Andricvoid __deferred_assoc_state<_Rp, _Fp>::__execute() {
77606c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
777cb14a3feSDimitry Andric  try {
77806c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
7790b57cec5SDimitry Andric    this->set_value(__func_());
78006c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
781cb14a3feSDimitry Andric  } catch (...) {
7820b57cec5SDimitry Andric    this->set_exception(current_exception());
7830b57cec5SDimitry Andric  }
78406c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
7850b57cec5SDimitry Andric}
7860b57cec5SDimitry Andric
7870b57cec5SDimitry Andrictemplate <class _Fp>
788cb14a3feSDimitry Andricclass __deferred_assoc_state<void, _Fp> : public __assoc_sub_state {
7890b57cec5SDimitry Andric  typedef __assoc_sub_state base;
7900b57cec5SDimitry Andric
7910b57cec5SDimitry Andric  _Fp __func_;
7920b57cec5SDimitry Andric
7930b57cec5SDimitry Andricpublic:
794cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f);
7950b57cec5SDimitry Andric
79606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
7970b57cec5SDimitry Andric};
7980b57cec5SDimitry Andric
7990b57cec5SDimitry Andrictemplate <class _Fp>
800cb14a3feSDimitry Andricinline __deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {
8010b57cec5SDimitry Andric  this->__set_deferred();
8020b57cec5SDimitry Andric}
8030b57cec5SDimitry Andric
8040b57cec5SDimitry Andrictemplate <class _Fp>
805cb14a3feSDimitry Andricvoid __deferred_assoc_state<void, _Fp>::__execute() {
80606c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
807cb14a3feSDimitry Andric  try {
80806c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
8090b57cec5SDimitry Andric    __func_();
8100b57cec5SDimitry Andric    this->set_value();
81106c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
812cb14a3feSDimitry Andric  } catch (...) {
8130b57cec5SDimitry Andric    this->set_exception(current_exception());
8140b57cec5SDimitry Andric  }
81506c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
8160b57cec5SDimitry Andric}
8170b57cec5SDimitry Andric
8180b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
819cb14a3feSDimitry Andricclass __async_assoc_state : public __assoc_state<_Rp> {
8200b57cec5SDimitry Andric  typedef __assoc_state<_Rp> base;
8210b57cec5SDimitry Andric
8220b57cec5SDimitry Andric  _Fp __func_;
8230b57cec5SDimitry Andric
82406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
825cb14a3feSDimitry Andric
8260b57cec5SDimitry Andricpublic:
827cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f);
8280b57cec5SDimitry Andric
82906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
8300b57cec5SDimitry Andric};
8310b57cec5SDimitry Andric
8320b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
833cb14a3feSDimitry Andricinline __async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {}
8340b57cec5SDimitry Andric
8350b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
836cb14a3feSDimitry Andricvoid __async_assoc_state<_Rp, _Fp>::__execute() {
83706c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
838cb14a3feSDimitry Andric  try {
83906c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
8400b57cec5SDimitry Andric    this->set_value(__func_());
84106c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
842cb14a3feSDimitry Andric  } catch (...) {
8430b57cec5SDimitry Andric    this->set_exception(current_exception());
8440b57cec5SDimitry Andric  }
84506c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
8460b57cec5SDimitry Andric}
8470b57cec5SDimitry Andric
8480b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
849cb14a3feSDimitry Andricvoid __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT {
8500b57cec5SDimitry Andric  this->wait();
8510b57cec5SDimitry Andric  base::__on_zero_shared();
8520b57cec5SDimitry Andric}
8530b57cec5SDimitry Andric
8540b57cec5SDimitry Andrictemplate <class _Fp>
855cb14a3feSDimitry Andricclass __async_assoc_state<void, _Fp> : public __assoc_sub_state {
8560b57cec5SDimitry Andric  typedef __assoc_sub_state base;
8570b57cec5SDimitry Andric
8580b57cec5SDimitry Andric  _Fp __func_;
8590b57cec5SDimitry Andric
86006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
861cb14a3feSDimitry Andric
8620b57cec5SDimitry Andricpublic:
863cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f);
8640b57cec5SDimitry Andric
86506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
8660b57cec5SDimitry Andric};
8670b57cec5SDimitry Andric
8680b57cec5SDimitry Andrictemplate <class _Fp>
869cb14a3feSDimitry Andricinline __async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {}
8700b57cec5SDimitry Andric
8710b57cec5SDimitry Andrictemplate <class _Fp>
872cb14a3feSDimitry Andricvoid __async_assoc_state<void, _Fp>::__execute() {
87306c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
874cb14a3feSDimitry Andric  try {
87506c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
8760b57cec5SDimitry Andric    __func_();
8770b57cec5SDimitry Andric    this->set_value();
87806c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
879cb14a3feSDimitry Andric  } catch (...) {
8800b57cec5SDimitry Andric    this->set_exception(current_exception());
8810b57cec5SDimitry Andric  }
88206c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
8830b57cec5SDimitry Andric}
8840b57cec5SDimitry Andric
8850b57cec5SDimitry Andrictemplate <class _Fp>
886cb14a3feSDimitry Andricvoid __async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT {
8870b57cec5SDimitry Andric  this->wait();
8880b57cec5SDimitry Andric  base::__on_zero_shared();
8890b57cec5SDimitry Andric}
8900b57cec5SDimitry Andric
891cb14a3feSDimitry Andrictemplate <class _Rp>
892cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise;
893cb14a3feSDimitry Andrictemplate <class _Rp>
894cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future;
8950b57cec5SDimitry Andric
8960b57cec5SDimitry Andric// future
8970b57cec5SDimitry Andric
898cb14a3feSDimitry Andrictemplate <class _Rp>
899cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future;
9000b57cec5SDimitry Andric
9010b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
902cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f);
9030b57cec5SDimitry Andric
9040b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
905cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f);
9060b57cec5SDimitry Andric
9070b57cec5SDimitry Andrictemplate <class _Rp>
908cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future {
9090b57cec5SDimitry Andric  __assoc_state<_Rp>* __state_;
9100b57cec5SDimitry Andric
91106c3fb27SDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state);
9120b57cec5SDimitry Andric
913cb14a3feSDimitry Andric  template <class>
914cb14a3feSDimitry Andric  friend class promise;
915cb14a3feSDimitry Andric  template <class>
916cb14a3feSDimitry Andric  friend class shared_future;
9170b57cec5SDimitry Andric
9180b57cec5SDimitry Andric  template <class _R1, class _Fp>
9190b57cec5SDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
9200b57cec5SDimitry Andric  template <class _R1, class _Fp>
9210b57cec5SDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
9220b57cec5SDimitry Andric
9230b57cec5SDimitry Andricpublic:
924cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
925cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
9260b57cec5SDimitry Andric  future(const future&)            = delete;
9270b57cec5SDimitry Andric  future& operator=(const future&) = delete;
928cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
9295f757f3fSDimitry Andric    future(std::move(__rhs)).swap(*this);
9300b57cec5SDimitry Andric    return *this;
9310b57cec5SDimitry Andric  }
932e8d8bef9SDimitry Andric
93306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~future();
934cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<_Rp> share() _NOEXCEPT;
9350b57cec5SDimitry Andric
9360b57cec5SDimitry Andric  // retrieving the value
93706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp get();
9380b57cec5SDimitry Andric
939cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
9400b57cec5SDimitry Andric
9410b57cec5SDimitry Andric  // functions to check state
942cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
9430b57cec5SDimitry Andric
944cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
9450b57cec5SDimitry Andric  template <class _Rep, class _Period>
946cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
947cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
948cb14a3feSDimitry Andric  }
9490b57cec5SDimitry Andric  template <class _Clock, class _Duration>
950cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
951cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
952cb14a3feSDimitry Andric  }
9530b57cec5SDimitry Andric};
9540b57cec5SDimitry Andric
9550b57cec5SDimitry Andrictemplate <class _Rp>
956cb14a3feSDimitry Andricfuture<_Rp>::future(__assoc_state<_Rp>* __state) : __state_(__state) {
9570b57cec5SDimitry Andric  __state_->__attach_future();
9580b57cec5SDimitry Andric}
9590b57cec5SDimitry Andric
960cb14a3feSDimitry Andricstruct __release_shared_count {
96106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) { __p->__release_shared(); }
9620b57cec5SDimitry Andric};
9630b57cec5SDimitry Andric
9640b57cec5SDimitry Andrictemplate <class _Rp>
965cb14a3feSDimitry Andricfuture<_Rp>::~future() {
9660b57cec5SDimitry Andric  if (__state_)
9670b57cec5SDimitry Andric    __state_->__release_shared();
9680b57cec5SDimitry Andric}
9690b57cec5SDimitry Andric
9700b57cec5SDimitry Andrictemplate <class _Rp>
971cb14a3feSDimitry Andric_Rp future<_Rp>::get() {
97206c3fb27SDimitry Andric  unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
9730b57cec5SDimitry Andric  __assoc_state<_Rp>* __s = __state_;
9740b57cec5SDimitry Andric  __state_                = nullptr;
9750b57cec5SDimitry Andric  return __s->move();
9760b57cec5SDimitry Andric}
9770b57cec5SDimitry Andric
9780b57cec5SDimitry Andrictemplate <class _Rp>
979cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future<_Rp&> {
9800b57cec5SDimitry Andric  __assoc_state<_Rp&>* __state_;
9810b57cec5SDimitry Andric
98206c3fb27SDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state);
9830b57cec5SDimitry Andric
984cb14a3feSDimitry Andric  template <class>
985cb14a3feSDimitry Andric  friend class promise;
986cb14a3feSDimitry Andric  template <class>
987cb14a3feSDimitry Andric  friend class shared_future;
9880b57cec5SDimitry Andric
9890b57cec5SDimitry Andric  template <class _R1, class _Fp>
9900b57cec5SDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
9910b57cec5SDimitry Andric  template <class _R1, class _Fp>
9920b57cec5SDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
9930b57cec5SDimitry Andric
9940b57cec5SDimitry Andricpublic:
995cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
996cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
9970b57cec5SDimitry Andric  future(const future&)            = delete;
9980b57cec5SDimitry Andric  future& operator=(const future&) = delete;
999cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
10005f757f3fSDimitry Andric    future(std::move(__rhs)).swap(*this);
10010b57cec5SDimitry Andric    return *this;
10020b57cec5SDimitry Andric  }
1003e8d8bef9SDimitry Andric
100406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~future();
1005cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<_Rp&> share() _NOEXCEPT;
10060b57cec5SDimitry Andric
10070b57cec5SDimitry Andric  // retrieving the value
100806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& get();
10090b57cec5SDimitry Andric
1010cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
10110b57cec5SDimitry Andric
10120b57cec5SDimitry Andric  // functions to check state
1013cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
10140b57cec5SDimitry Andric
1015cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
10160b57cec5SDimitry Andric  template <class _Rep, class _Period>
1017cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1018cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1019cb14a3feSDimitry Andric  }
10200b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1021cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1022cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1023cb14a3feSDimitry Andric  }
10240b57cec5SDimitry Andric};
10250b57cec5SDimitry Andric
10260b57cec5SDimitry Andrictemplate <class _Rp>
1027cb14a3feSDimitry Andricfuture<_Rp&>::future(__assoc_state<_Rp&>* __state) : __state_(__state) {
10280b57cec5SDimitry Andric  __state_->__attach_future();
10290b57cec5SDimitry Andric}
10300b57cec5SDimitry Andric
10310b57cec5SDimitry Andrictemplate <class _Rp>
1032cb14a3feSDimitry Andricfuture<_Rp&>::~future() {
10330b57cec5SDimitry Andric  if (__state_)
10340b57cec5SDimitry Andric    __state_->__release_shared();
10350b57cec5SDimitry Andric}
10360b57cec5SDimitry Andric
10370b57cec5SDimitry Andrictemplate <class _Rp>
1038cb14a3feSDimitry Andric_Rp& future<_Rp&>::get() {
103906c3fb27SDimitry Andric  unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
10400b57cec5SDimitry Andric  __assoc_state<_Rp&>* __s = __state_;
10410b57cec5SDimitry Andric  __state_                 = nullptr;
10420b57cec5SDimitry Andric  return __s->copy();
10430b57cec5SDimitry Andric}
10440b57cec5SDimitry Andric
10450b57cec5SDimitry Andrictemplate <>
1046cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future<void> {
10470b57cec5SDimitry Andric  __assoc_sub_state* __state_;
10480b57cec5SDimitry Andric
10490b57cec5SDimitry Andric  explicit future(__assoc_sub_state* __state);
10500b57cec5SDimitry Andric
1051cb14a3feSDimitry Andric  template <class>
1052cb14a3feSDimitry Andric  friend class promise;
1053cb14a3feSDimitry Andric  template <class>
1054cb14a3feSDimitry Andric  friend class shared_future;
10550b57cec5SDimitry Andric
10560b57cec5SDimitry Andric  template <class _R1, class _Fp>
10570b57cec5SDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
10580b57cec5SDimitry Andric  template <class _R1, class _Fp>
10590b57cec5SDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
10600b57cec5SDimitry Andric
10610b57cec5SDimitry Andricpublic:
1062cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
1063cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
10640b57cec5SDimitry Andric  future(const future&)            = delete;
10650b57cec5SDimitry Andric  future& operator=(const future&) = delete;
1066cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
10675f757f3fSDimitry Andric    future(std::move(__rhs)).swap(*this);
10680b57cec5SDimitry Andric    return *this;
10690b57cec5SDimitry Andric  }
1070e8d8bef9SDimitry Andric
10710b57cec5SDimitry Andric  ~future();
1072cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<void> share() _NOEXCEPT;
10730b57cec5SDimitry Andric
10740b57cec5SDimitry Andric  // retrieving the value
10750b57cec5SDimitry Andric  void get();
10760b57cec5SDimitry Andric
1077cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
10780b57cec5SDimitry Andric
10790b57cec5SDimitry Andric  // functions to check state
1080cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
10810b57cec5SDimitry Andric
1082cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
10830b57cec5SDimitry Andric  template <class _Rep, class _Period>
1084cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1085cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1086cb14a3feSDimitry Andric  }
10870b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1088cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1089cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1090cb14a3feSDimitry Andric  }
10910b57cec5SDimitry Andric};
10920b57cec5SDimitry Andric
10930b57cec5SDimitry Andrictemplate <class _Rp>
1094cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT {
10950b57cec5SDimitry Andric  __x.swap(__y);
10960b57cec5SDimitry Andric}
10970b57cec5SDimitry Andric
10980b57cec5SDimitry Andric// promise<R>
10990b57cec5SDimitry Andric
1100cb14a3feSDimitry Andrictemplate <class _Callable>
1101cb14a3feSDimitry Andricclass packaged_task;
11020b57cec5SDimitry Andric
11030b57cec5SDimitry Andrictemplate <class _Rp>
1104cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise {
11050b57cec5SDimitry Andric  __assoc_state<_Rp>* __state_;
11060b57cec5SDimitry Andric
1107cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
11080b57cec5SDimitry Andric
1109cb14a3feSDimitry Andric  template <class>
1110cb14a3feSDimitry Andric  friend class packaged_task;
1111cb14a3feSDimitry Andric
11120b57cec5SDimitry Andricpublic:
111306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise();
11140b57cec5SDimitry Andric  template <class _Alloc>
111506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a);
1116cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
11170b57cec5SDimitry Andric  promise(const promise& __rhs) = delete;
111806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~promise();
11190b57cec5SDimitry Andric
11200b57cec5SDimitry Andric  // assignment
1121cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
11225f757f3fSDimitry Andric    promise(std::move(__rhs)).swap(*this);
11230b57cec5SDimitry Andric    return *this;
11240b57cec5SDimitry Andric  }
11250b57cec5SDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1126e8d8bef9SDimitry Andric
1127cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
11280b57cec5SDimitry Andric
11290b57cec5SDimitry Andric  // retrieving the result
113006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future();
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andric  // setting the result
113306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r);
113406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r);
113506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
11360b57cec5SDimitry Andric
11370b57cec5SDimitry Andric  // setting the result with deferred notification
113806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r);
113906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r);
114006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
11410b57cec5SDimitry Andric};
11420b57cec5SDimitry Andric
11430b57cec5SDimitry Andrictemplate <class _Rp>
1144cb14a3feSDimitry Andricpromise<_Rp>::promise() : __state_(new __assoc_state<_Rp>) {}
11450b57cec5SDimitry Andric
11460b57cec5SDimitry Andrictemplate <class _Rp>
11470b57cec5SDimitry Andrictemplate <class _Alloc>
1148cb14a3feSDimitry Andricpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) {
11490b57cec5SDimitry Andric  typedef __assoc_state_alloc<_Rp, _Alloc> _State;
11500b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
11510b57cec5SDimitry Andric  typedef __allocator_destructor<_A2> _D2;
11520b57cec5SDimitry Andric  _A2 __a(__a0);
11530b57cec5SDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
11545f757f3fSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
11555f757f3fSDimitry Andric  __state_ = std::addressof(*__hold.release());
11560b57cec5SDimitry Andric}
11570b57cec5SDimitry Andric
11580b57cec5SDimitry Andrictemplate <class _Rp>
1159cb14a3feSDimitry Andricpromise<_Rp>::~promise() {
1160cb14a3feSDimitry Andric  if (__state_) {
11610b57cec5SDimitry Andric    if (!__state_->__has_value() && __state_->use_count() > 1)
11625f757f3fSDimitry Andric      __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise))));
11630b57cec5SDimitry Andric    __state_->__release_shared();
11640b57cec5SDimitry Andric  }
11650b57cec5SDimitry Andric}
11660b57cec5SDimitry Andric
11670b57cec5SDimitry Andrictemplate <class _Rp>
1168cb14a3feSDimitry Andricfuture<_Rp> promise<_Rp>::get_future() {
11690b57cec5SDimitry Andric  if (__state_ == nullptr)
11700b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11710b57cec5SDimitry Andric  return future<_Rp>(__state_);
11720b57cec5SDimitry Andric}
11730b57cec5SDimitry Andric
11740b57cec5SDimitry Andrictemplate <class _Rp>
1175cb14a3feSDimitry Andricvoid promise<_Rp>::set_value(const _Rp& __r) {
11760b57cec5SDimitry Andric  if (__state_ == nullptr)
11770b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11780b57cec5SDimitry Andric  __state_->set_value(__r);
11790b57cec5SDimitry Andric}
11800b57cec5SDimitry Andric
11810b57cec5SDimitry Andrictemplate <class _Rp>
1182cb14a3feSDimitry Andricvoid promise<_Rp>::set_value(_Rp&& __r) {
11830b57cec5SDimitry Andric  if (__state_ == nullptr)
11840b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11855f757f3fSDimitry Andric  __state_->set_value(std::move(__r));
11860b57cec5SDimitry Andric}
11870b57cec5SDimitry Andric
11880b57cec5SDimitry Andrictemplate <class _Rp>
1189cb14a3feSDimitry Andricvoid promise<_Rp>::set_exception(exception_ptr __p) {
11905f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr");
11910b57cec5SDimitry Andric  if (__state_ == nullptr)
11920b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
11930b57cec5SDimitry Andric  __state_->set_exception(__p);
11940b57cec5SDimitry Andric}
11950b57cec5SDimitry Andric
11960b57cec5SDimitry Andrictemplate <class _Rp>
1197cb14a3feSDimitry Andricvoid promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) {
11980b57cec5SDimitry Andric  if (__state_ == nullptr)
11990b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12000b57cec5SDimitry Andric  __state_->set_value_at_thread_exit(__r);
12010b57cec5SDimitry Andric}
12020b57cec5SDimitry Andric
12030b57cec5SDimitry Andrictemplate <class _Rp>
1204cb14a3feSDimitry Andricvoid promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) {
12050b57cec5SDimitry Andric  if (__state_ == nullptr)
12060b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12075f757f3fSDimitry Andric  __state_->set_value_at_thread_exit(std::move(__r));
12080b57cec5SDimitry Andric}
12090b57cec5SDimitry Andric
12100b57cec5SDimitry Andrictemplate <class _Rp>
1211cb14a3feSDimitry Andricvoid promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) {
12125f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr");
12130b57cec5SDimitry Andric  if (__state_ == nullptr)
12140b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12150b57cec5SDimitry Andric  __state_->set_exception_at_thread_exit(__p);
12160b57cec5SDimitry Andric}
12170b57cec5SDimitry Andric
12180b57cec5SDimitry Andric// promise<R&>
12190b57cec5SDimitry Andric
12200b57cec5SDimitry Andrictemplate <class _Rp>
1221cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise<_Rp&> {
12220b57cec5SDimitry Andric  __assoc_state<_Rp&>* __state_;
12230b57cec5SDimitry Andric
1224cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
12250b57cec5SDimitry Andric
1226cb14a3feSDimitry Andric  template <class>
1227cb14a3feSDimitry Andric  friend class packaged_task;
12280b57cec5SDimitry Andric
12290b57cec5SDimitry Andricpublic:
123006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise();
12310b57cec5SDimitry Andric  template <class _Allocator>
123206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a);
1233cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
12340b57cec5SDimitry Andric  promise(const promise& __rhs) = delete;
123506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~promise();
12360b57cec5SDimitry Andric
12370b57cec5SDimitry Andric  // assignment
1238cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
12395f757f3fSDimitry Andric    promise(std::move(__rhs)).swap(*this);
12400b57cec5SDimitry Andric    return *this;
12410b57cec5SDimitry Andric  }
12420b57cec5SDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1243e8d8bef9SDimitry Andric
1244cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
12450b57cec5SDimitry Andric
12460b57cec5SDimitry Andric  // retrieving the result
124706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future();
12480b57cec5SDimitry Andric
12490b57cec5SDimitry Andric  // setting the result
125006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r);
125106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
12520b57cec5SDimitry Andric
12530b57cec5SDimitry Andric  // setting the result with deferred notification
125406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&);
125506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
12560b57cec5SDimitry Andric};
12570b57cec5SDimitry Andric
12580b57cec5SDimitry Andrictemplate <class _Rp>
1259cb14a3feSDimitry Andricpromise<_Rp&>::promise() : __state_(new __assoc_state<_Rp&>) {}
12600b57cec5SDimitry Andric
12610b57cec5SDimitry Andrictemplate <class _Rp>
12620b57cec5SDimitry Andrictemplate <class _Alloc>
1263cb14a3feSDimitry Andricpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) {
12640b57cec5SDimitry Andric  typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
12650b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
12660b57cec5SDimitry Andric  typedef __allocator_destructor<_A2> _D2;
12670b57cec5SDimitry Andric  _A2 __a(__a0);
12680b57cec5SDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
12695f757f3fSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
12705f757f3fSDimitry Andric  __state_ = std::addressof(*__hold.release());
12710b57cec5SDimitry Andric}
12720b57cec5SDimitry Andric
12730b57cec5SDimitry Andrictemplate <class _Rp>
1274cb14a3feSDimitry Andricpromise<_Rp&>::~promise() {
1275cb14a3feSDimitry Andric  if (__state_) {
12760b57cec5SDimitry Andric    if (!__state_->__has_value() && __state_->use_count() > 1)
12775f757f3fSDimitry Andric      __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise))));
12780b57cec5SDimitry Andric    __state_->__release_shared();
12790b57cec5SDimitry Andric  }
12800b57cec5SDimitry Andric}
12810b57cec5SDimitry Andric
12820b57cec5SDimitry Andrictemplate <class _Rp>
1283cb14a3feSDimitry Andricfuture<_Rp&> promise<_Rp&>::get_future() {
12840b57cec5SDimitry Andric  if (__state_ == nullptr)
12850b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12860b57cec5SDimitry Andric  return future<_Rp&>(__state_);
12870b57cec5SDimitry Andric}
12880b57cec5SDimitry Andric
12890b57cec5SDimitry Andrictemplate <class _Rp>
1290cb14a3feSDimitry Andricvoid promise<_Rp&>::set_value(_Rp& __r) {
12910b57cec5SDimitry Andric  if (__state_ == nullptr)
12920b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
12930b57cec5SDimitry Andric  __state_->set_value(__r);
12940b57cec5SDimitry Andric}
12950b57cec5SDimitry Andric
12960b57cec5SDimitry Andrictemplate <class _Rp>
1297cb14a3feSDimitry Andricvoid promise<_Rp&>::set_exception(exception_ptr __p) {
12985f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr");
12990b57cec5SDimitry Andric  if (__state_ == nullptr)
13000b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
13010b57cec5SDimitry Andric  __state_->set_exception(__p);
13020b57cec5SDimitry Andric}
13030b57cec5SDimitry Andric
13040b57cec5SDimitry Andrictemplate <class _Rp>
1305cb14a3feSDimitry Andricvoid promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) {
13060b57cec5SDimitry Andric  if (__state_ == nullptr)
13070b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
13080b57cec5SDimitry Andric  __state_->set_value_at_thread_exit(__r);
13090b57cec5SDimitry Andric}
13100b57cec5SDimitry Andric
13110b57cec5SDimitry Andrictemplate <class _Rp>
1312cb14a3feSDimitry Andricvoid promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) {
13135f757f3fSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr");
13140b57cec5SDimitry Andric  if (__state_ == nullptr)
13150b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
13160b57cec5SDimitry Andric  __state_->set_exception_at_thread_exit(__p);
13170b57cec5SDimitry Andric}
13180b57cec5SDimitry Andric
13190b57cec5SDimitry Andric// promise<void>
13200b57cec5SDimitry Andric
13210b57cec5SDimitry Andrictemplate <>
1322cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI promise<void> {
13230b57cec5SDimitry Andric  __assoc_sub_state* __state_;
13240b57cec5SDimitry Andric
1325cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
13260b57cec5SDimitry Andric
1327cb14a3feSDimitry Andric  template <class>
1328cb14a3feSDimitry Andric  friend class packaged_task;
13290b57cec5SDimitry Andric
13300b57cec5SDimitry Andricpublic:
13310b57cec5SDimitry Andric  promise();
13320b57cec5SDimitry Andric  template <class _Allocator>
1333cb14a3feSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS promise(allocator_arg_t, const _Allocator& __a);
1334cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
13350b57cec5SDimitry Andric  promise(const promise& __rhs) = delete;
13360b57cec5SDimitry Andric  ~promise();
13370b57cec5SDimitry Andric
13380b57cec5SDimitry Andric  // assignment
1339cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
13405f757f3fSDimitry Andric    promise(std::move(__rhs)).swap(*this);
13410b57cec5SDimitry Andric    return *this;
13420b57cec5SDimitry Andric  }
13430b57cec5SDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1344e8d8bef9SDimitry Andric
1345cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
13460b57cec5SDimitry Andric
13470b57cec5SDimitry Andric  // retrieving the result
13480b57cec5SDimitry Andric  future<void> get_future();
13490b57cec5SDimitry Andric
13500b57cec5SDimitry Andric  // setting the result
13510b57cec5SDimitry Andric  void set_value();
13520b57cec5SDimitry Andric  void set_exception(exception_ptr __p);
13530b57cec5SDimitry Andric
13540b57cec5SDimitry Andric  // setting the result with deferred notification
13550b57cec5SDimitry Andric  void set_value_at_thread_exit();
13560b57cec5SDimitry Andric  void set_exception_at_thread_exit(exception_ptr __p);
13570b57cec5SDimitry Andric};
13580b57cec5SDimitry Andric
13590b57cec5SDimitry Andrictemplate <class _Alloc>
1360cb14a3feSDimitry Andricpromise<void>::promise(allocator_arg_t, const _Alloc& __a0) {
13610b57cec5SDimitry Andric  typedef __assoc_sub_state_alloc<_Alloc> _State;
13620b57cec5SDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
13630b57cec5SDimitry Andric  typedef __allocator_destructor<_A2> _D2;
13640b57cec5SDimitry Andric  _A2 __a(__a0);
13650b57cec5SDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
13665f757f3fSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
13675f757f3fSDimitry Andric  __state_ = std::addressof(*__hold.release());
13680b57cec5SDimitry Andric}
13690b57cec5SDimitry Andric
13700b57cec5SDimitry Andrictemplate <class _Rp>
1371cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT {
13720b57cec5SDimitry Andric  __x.swap(__y);
13730b57cec5SDimitry Andric}
13740b57cec5SDimitry Andric
13750b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
1376cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc> : public true_type {};
13770b57cec5SDimitry Andric
13780b57cec5SDimitry Andric// packaged_task
13790b57cec5SDimitry Andric
1380cb14a3feSDimitry Andrictemplate <class _Fp>
1381cb14a3feSDimitry Andricclass __packaged_task_base;
13820b57cec5SDimitry Andric
13830b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1384cb14a3feSDimitry Andricclass __packaged_task_base<_Rp(_ArgTypes...)> {
13850b57cec5SDimitry Andricpublic:
1386cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_base() {}
1387*0fca6ea1SDimitry Andric  __packaged_task_base(const __packaged_task_base&)            = delete;
1388*0fca6ea1SDimitry Andric  __packaged_task_base& operator=(const __packaged_task_base&) = delete;
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
1397cb14a3feSDimitry Andrictemplate <class _FD, class _Alloc, class _FB>
1398cb14a3feSDimitry Andricclass __packaged_task_func;
13990b57cec5SDimitry Andric
14000b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1401cb14a3feSDimitry Andricclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __packaged_task_base<_Rp(_ArgTypes...)> {
14020b57cec5SDimitry Andric  __compressed_pair<_Fp, _Alloc> __f_;
1403cb14a3feSDimitry Andric
14040b57cec5SDimitry Andricpublic:
1405cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
1406cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(_Fp&& __f) : __f_(std::move(__f), __default_init_tag()) {}
1407cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {}
1408cb14a3feSDimitry 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>
1416cb14a3feSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1417cb14a3feSDimitry 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>
1422cb14a3feSDimitry 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>
1427cb14a3feSDimitry 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>
1437cb14a3feSDimitry 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
1441cb14a3feSDimitry Andrictemplate <class _Callable>
1442cb14a3feSDimitry Andricclass __packaged_task_function;
14430b57cec5SDimitry Andric
14440b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1445cb14a3feSDimitry Andricclass __packaged_task_function<_Rp(_ArgTypes...)> {
14460b57cec5SDimitry Andric  typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1447e8d8bef9SDimitry Andric
1448cb14a3feSDimitry 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:
1459cb14a3feSDimitry 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
1475cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
14760b57cec5SDimitry Andric};
14770b57cec5SDimitry Andric
14780b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1479cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT {
14800b57cec5SDimitry Andric  if (__f.__f_ == nullptr)
14810b57cec5SDimitry Andric    __f_ = nullptr;
1482cb14a3feSDimitry Andric  else if (__f.__f_ == __f.__get_buf()) {
1483e8d8bef9SDimitry Andric    __f.__f_->__move_to(__get_buf());
14840b57cec5SDimitry Andric    __f_ = (__base*)&__buf_;
1485cb14a3feSDimitry 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>
1493cb14a3feSDimitry 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;
1496cb14a3feSDimitry Andric  if (sizeof(_FF) <= sizeof(__buf_)) {
14975f757f3fSDimitry Andric    ::new ((void*)&__buf_) _FF(std::forward<_Fp>(__f));
14980b57cec5SDimitry Andric    __f_ = (__base*)&__buf_;
1499cb14a3feSDimitry 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>
1511cb14a3feSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1512cb14a3feSDimitry 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;
1515cb14a3feSDimitry Andric  if (sizeof(_FF) <= sizeof(__buf_)) {
15160b57cec5SDimitry Andric    __f_ = (__base*)&__buf_;
15175f757f3fSDimitry Andric    ::new ((void*)__f_) _FF(std::forward<_Fp>(__f));
1518cb14a3feSDimitry 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));
1523cb14a3feSDimitry 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...)>&
1530cb14a3feSDimitry 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;
1538cb14a3feSDimitry Andric  else if (__f.__f_ == __f.__get_buf()) {
1539e8d8bef9SDimitry Andric    __f.__f_->__move_to(__get_buf());
1540e8d8bef9SDimitry Andric    __f_ = __get_buf();
1541cb14a3feSDimitry 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>
1549cb14a3feSDimitry 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>
1557cb14a3feSDimitry Andric_LIBCPP_NO_CFI void __packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT {
1558cb14a3feSDimitry 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_;
1573cb14a3feSDimitry 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_;
1578cb14a3feSDimitry 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_;
1583cb14a3feSDimitry Andric  } else
15845f757f3fSDimitry Andric    std::swap(__f_, __f.__f_);
15850b57cec5SDimitry Andric}
15860b57cec5SDimitry Andric
15870b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1588cb14a3feSDimitry 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>
1593cb14a3feSDimitry 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
1603cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}
1604*0fca6ea1SDimitry Andric
1605*0fca6ea1SDimitry Andric  template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
1606cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
1607*0fca6ea1SDimitry Andric
1608*0fca6ea1SDimitry Andric  template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
1609cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1610cb14a3feSDimitry Andric      : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
16110b57cec5SDimitry Andric  // ~packaged_task() = default;
16120b57cec5SDimitry Andric
16130b57cec5SDimitry Andric  // no copy
16140b57cec5SDimitry Andric  packaged_task(const packaged_task&)            = delete;
16150b57cec5SDimitry Andric  packaged_task& operator=(const packaged_task&) = delete;
16160b57cec5SDimitry Andric
16170b57cec5SDimitry Andric  // move support
1618cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT
1619cb14a3feSDimitry Andric      : __f_(std::move(__other.__f_)),
1620cb14a3feSDimitry Andric        __p_(std::move(__other.__p_)) {}
1621cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT {
16225f757f3fSDimitry Andric    __f_ = std::move(__other.__f_);
16235f757f3fSDimitry Andric    __p_ = std::move(__other.__p_);
16240b57cec5SDimitry Andric    return *this;
16250b57cec5SDimitry Andric  }
1626cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT {
16270b57cec5SDimitry Andric    __f_.swap(__other.__f_);
16280b57cec5SDimitry Andric    __p_.swap(__other.__p_);
16290b57cec5SDimitry Andric  }
16300b57cec5SDimitry Andric
1631cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
16320b57cec5SDimitry Andric
16330b57cec5SDimitry Andric  // result retrieval
1634cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); }
16350b57cec5SDimitry Andric
16360b57cec5SDimitry Andric  // execution
163706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
163806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
16390b57cec5SDimitry Andric
164006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reset();
16410b57cec5SDimitry Andric};
16420b57cec5SDimitry Andric
16430b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1644cb14a3feSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) {
16450b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
16460b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
16470b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
16480b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
164906c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1650cb14a3feSDimitry Andric  try {
165106c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
16525f757f3fSDimitry Andric    __p_.set_value(__f_(std::forward<_ArgTypes>(__args)...));
165306c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1654cb14a3feSDimitry Andric  } catch (...) {
16550b57cec5SDimitry Andric    __p_.set_exception(current_exception());
16560b57cec5SDimitry Andric  }
165706c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
16580b57cec5SDimitry Andric}
16590b57cec5SDimitry Andric
16600b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1661cb14a3feSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {
16620b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
16630b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
16640b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
16650b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
166606c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1667cb14a3feSDimitry Andric  try {
166806c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
16695f757f3fSDimitry Andric    __p_.set_value_at_thread_exit(__f_(std::forward<_ArgTypes>(__args)...));
167006c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1671cb14a3feSDimitry Andric  } catch (...) {
16720b57cec5SDimitry Andric    __p_.set_exception_at_thread_exit(current_exception());
16730b57cec5SDimitry Andric  }
167406c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
16750b57cec5SDimitry Andric}
16760b57cec5SDimitry Andric
16770b57cec5SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1678cb14a3feSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::reset() {
16790b57cec5SDimitry Andric  if (!valid())
16800b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
16810b57cec5SDimitry Andric  __p_ = promise<result_type>();
16820b57cec5SDimitry Andric}
16830b57cec5SDimitry Andric
16840b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1685cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<void(_ArgTypes...)> {
16860b57cec5SDimitry Andricpublic:
16870b57cec5SDimitry Andric  typedef void result_type; // extension
16880b57cec5SDimitry Andric
16890b57cec5SDimitry Andricprivate:
16900b57cec5SDimitry Andric  __packaged_task_function<result_type(_ArgTypes...)> __f_;
16910b57cec5SDimitry Andric  promise<result_type> __p_;
16920b57cec5SDimitry Andric
16930b57cec5SDimitry Andricpublic:
16940b57cec5SDimitry Andric  // construction and destruction
1695cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}
1696*0fca6ea1SDimitry Andric  template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
1697cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
1698*0fca6ea1SDimitry Andric  template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
1699cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1700cb14a3feSDimitry Andric      : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
17010b57cec5SDimitry Andric  // ~packaged_task() = default;
17020b57cec5SDimitry Andric
17030b57cec5SDimitry Andric  // no copy
17040b57cec5SDimitry Andric  packaged_task(const packaged_task&)            = delete;
17050b57cec5SDimitry Andric  packaged_task& operator=(const packaged_task&) = delete;
17060b57cec5SDimitry Andric
17070b57cec5SDimitry Andric  // move support
1708cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT
1709cb14a3feSDimitry Andric      : __f_(std::move(__other.__f_)),
1710cb14a3feSDimitry Andric        __p_(std::move(__other.__p_)) {}
1711cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT {
17125f757f3fSDimitry Andric    __f_ = std::move(__other.__f_);
17135f757f3fSDimitry Andric    __p_ = std::move(__other.__p_);
17140b57cec5SDimitry Andric    return *this;
17150b57cec5SDimitry Andric  }
1716cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT {
17170b57cec5SDimitry Andric    __f_.swap(__other.__f_);
17180b57cec5SDimitry Andric    __p_.swap(__other.__p_);
17190b57cec5SDimitry Andric  }
17200b57cec5SDimitry Andric
1721cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
17220b57cec5SDimitry Andric
17230b57cec5SDimitry Andric  // result retrieval
1724cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); }
17250b57cec5SDimitry Andric
17260b57cec5SDimitry Andric  // execution
172706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
172806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
17290b57cec5SDimitry Andric
173006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reset();
17310b57cec5SDimitry Andric};
17320b57cec5SDimitry Andric
1733bdd1243dSDimitry Andric#  if _LIBCPP_STD_VER >= 17
1734bdd1243dSDimitry Andric
1735bdd1243dSDimitry Andrictemplate <class _Rp, class... _Args>
1736bdd1243dSDimitry Andricpackaged_task(_Rp (*)(_Args...)) -> packaged_task<_Rp(_Args...)>;
1737bdd1243dSDimitry Andric
1738bdd1243dSDimitry Andrictemplate <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
1739bdd1243dSDimitry Andricpackaged_task(_Fp) -> packaged_task<_Stripped>;
1740bdd1243dSDimitry Andric
1741bdd1243dSDimitry Andric#  endif
1742bdd1243dSDimitry Andric
17430b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1744cb14a3feSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) {
17450b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
17460b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
17470b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
17480b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
174906c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1750cb14a3feSDimitry Andric  try {
175106c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
17525f757f3fSDimitry Andric    __f_(std::forward<_ArgTypes>(__args)...);
17530b57cec5SDimitry Andric    __p_.set_value();
175406c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1755cb14a3feSDimitry Andric  } catch (...) {
17560b57cec5SDimitry Andric    __p_.set_exception(current_exception());
17570b57cec5SDimitry Andric  }
175806c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
17590b57cec5SDimitry Andric}
17600b57cec5SDimitry Andric
17610b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1762cb14a3feSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {
17630b57cec5SDimitry Andric  if (__p_.__state_ == nullptr)
17640b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
17650b57cec5SDimitry Andric  if (__p_.__state_->__has_value())
17660b57cec5SDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
176706c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1768cb14a3feSDimitry Andric  try {
176906c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
17705f757f3fSDimitry Andric    __f_(std::forward<_ArgTypes>(__args)...);
17710b57cec5SDimitry Andric    __p_.set_value_at_thread_exit();
177206c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1773cb14a3feSDimitry Andric  } catch (...) {
17740b57cec5SDimitry Andric    __p_.set_exception_at_thread_exit(current_exception());
17750b57cec5SDimitry Andric  }
177606c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
17770b57cec5SDimitry Andric}
17780b57cec5SDimitry Andric
17790b57cec5SDimitry Andrictemplate <class... _ArgTypes>
1780cb14a3feSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::reset() {
17810b57cec5SDimitry Andric  if (!valid())
17820b57cec5SDimitry Andric    __throw_future_error(future_errc::no_state);
17830b57cec5SDimitry Andric  __p_ = promise<result_type>();
17840b57cec5SDimitry Andric}
17850b57cec5SDimitry Andric
1786fe6060f1SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1787cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
1788cb14a3feSDimitry Andricswap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT {
17890b57cec5SDimitry Andric  __x.swap(__y);
17900b57cec5SDimitry Andric}
17910b57cec5SDimitry Andric
17920b57cec5SDimitry Andrictemplate <class _Callable, class _Alloc>
1793cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {};
17940b57cec5SDimitry Andric
17950b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1796cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f) {
1797cb14a3feSDimitry Andric  unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
1798cb14a3feSDimitry Andric      new __deferred_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
17990b57cec5SDimitry Andric  return future<_Rp>(__h.get());
18000b57cec5SDimitry Andric}
18010b57cec5SDimitry Andric
18020b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1803cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f) {
1804cb14a3feSDimitry Andric  unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
1805cb14a3feSDimitry Andric      new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
18065f757f3fSDimitry Andric  std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
18070b57cec5SDimitry Andric  return future<_Rp>(__h.get());
18080b57cec5SDimitry Andric}
18090b57cec5SDimitry Andric
1810e8d8bef9SDimitry Andric#  ifndef _LIBCPP_CXX03_LANG
1811e8d8bef9SDimitry Andric
18120b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
1813cb14a3feSDimitry Andricclass _LIBCPP_HIDDEN __async_func {
18140b57cec5SDimitry Andric  tuple<_Fp, _Args...> __f_;
18150b57cec5SDimitry Andric
18160b57cec5SDimitry Andricpublic:
18170b57cec5SDimitry Andric  typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
18180b57cec5SDimitry Andric
1819cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_func(_Fp&& __f, _Args&&... __args)
18205f757f3fSDimitry Andric      : __f_(std::move(__f), std::move(__args)...) {}
18210b57cec5SDimitry Andric
1822cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __async_func(__async_func&& __f) : __f_(std::move(__f.__f_)) {}
18230b57cec5SDimitry Andric
1824cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp operator()() {
18250b57cec5SDimitry Andric    typedef typename __make_tuple_indices<1 + sizeof...(_Args), 1>::type _Index;
18260b57cec5SDimitry Andric    return __execute(_Index());
18270b57cec5SDimitry Andric  }
1828cb14a3feSDimitry Andric
18290b57cec5SDimitry Andricprivate:
18300b57cec5SDimitry Andric  template <size_t... _Indices>
1831cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp __execute(__tuple_indices<_Indices...>) {
18325f757f3fSDimitry Andric    return std::__invoke(std::move(std::get<0>(__f_)), std::move(std::get<_Indices>(__f_))...);
18330b57cec5SDimitry Andric  }
18340b57cec5SDimitry Andric};
18350b57cec5SDimitry Andric
1836cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool __does_policy_contain(launch __policy, launch __value) {
1837cb14a3feSDimitry Andric  return (int(__policy) & int(__value)) != 0;
1838cb14a3feSDimitry Andric}
18390b57cec5SDimitry Andric
18400b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
1841*0fca6ea1SDimitry Andric_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
1842cb14a3feSDimitry Andricasync(launch __policy, _Fp&& __f, _Args&&... __args) {
184306c3fb27SDimitry Andric  typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF;
18440b57cec5SDimitry Andric  typedef typename _BF::_Rp _Rp;
18450b57cec5SDimitry Andric
184606c3fb27SDimitry Andric#    ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1847cb14a3feSDimitry Andric  try {
18480b57cec5SDimitry Andric#    endif
18490b57cec5SDimitry Andric    if (__does_policy_contain(__policy, launch::async))
1850cb14a3feSDimitry Andric      return std::__make_async_assoc_state<_Rp>(
1851cb14a3feSDimitry Andric          _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...));
185206c3fb27SDimitry Andric#    ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1853cb14a3feSDimitry Andric  } catch (...) {
1854cb14a3feSDimitry Andric    if (__policy == launch::async)
1855cb14a3feSDimitry Andric      throw;
18560b57cec5SDimitry Andric  }
18570b57cec5SDimitry Andric#    endif
18580b57cec5SDimitry Andric
18590b57cec5SDimitry Andric  if (__does_policy_contain(__policy, launch::deferred))
1860cb14a3feSDimitry Andric    return std::__make_deferred_assoc_state<_Rp>(
1861cb14a3feSDimitry Andric        _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...));
18620b57cec5SDimitry Andric  return future<_Rp>{};
18630b57cec5SDimitry Andric}
18640b57cec5SDimitry Andric
18650b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
1866*0fca6ea1SDimitry Andric_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
1867cb14a3feSDimitry Andricasync(_Fp&& __f, _Args&&... __args) {
1868cb14a3feSDimitry 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>
1876cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future {
18770b57cec5SDimitry Andric  __assoc_state<_Rp>* __state_;
18780b57cec5SDimitry Andric
18790b57cec5SDimitry Andricpublic:
1880cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1881cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1882cb14a3feSDimitry Andric    if (__state_)
1883cb14a3feSDimitry Andric      __state_->__add_shared();
1884cb14a3feSDimitry Andric  }
1885cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1886cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1887cb14a3feSDimitry Andric    __rhs.__state_ = nullptr;
1888cb14a3feSDimitry Andric  }
188906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~shared_future();
189006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
1891cb14a3feSDimitry 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
1897cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const _Rp& get() const { return __state_->copy(); }
18980b57cec5SDimitry Andric
1899cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
19000b57cec5SDimitry Andric
19010b57cec5SDimitry Andric  // functions to check state
1902cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
19030b57cec5SDimitry Andric
1904cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
19050b57cec5SDimitry Andric  template <class _Rep, class _Period>
1906cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1907cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1908cb14a3feSDimitry Andric  }
19090b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1910cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1911cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1912cb14a3feSDimitry Andric  }
19130b57cec5SDimitry Andric};
19140b57cec5SDimitry Andric
19150b57cec5SDimitry Andrictemplate <class _Rp>
1916cb14a3feSDimitry Andricshared_future<_Rp>::~shared_future() {
19170b57cec5SDimitry Andric  if (__state_)
19180b57cec5SDimitry Andric    __state_->__release_shared();
19190b57cec5SDimitry Andric}
19200b57cec5SDimitry Andric
19210b57cec5SDimitry Andrictemplate <class _Rp>
1922cb14a3feSDimitry 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>
1932cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&> {
19330b57cec5SDimitry Andric  __assoc_state<_Rp&>* __state_;
19340b57cec5SDimitry Andric
19350b57cec5SDimitry Andricpublic:
1936cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1937cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {
1938cb14a3feSDimitry Andric    if (__state_)
1939cb14a3feSDimitry Andric      __state_->__add_shared();
1940cb14a3feSDimitry Andric  }
1941cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1942cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1943cb14a3feSDimitry Andric    __rhs.__state_ = nullptr;
1944cb14a3feSDimitry Andric  }
194506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~shared_future();
194606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs);
1947cb14a3feSDimitry 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
1953cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& get() const { return __state_->copy(); }
19540b57cec5SDimitry Andric
1955cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
19560b57cec5SDimitry Andric
19570b57cec5SDimitry Andric  // functions to check state
1958cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
19590b57cec5SDimitry Andric
1960cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
19610b57cec5SDimitry Andric  template <class _Rep, class _Period>
1962cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1963cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
1964cb14a3feSDimitry Andric  }
19650b57cec5SDimitry Andric  template <class _Clock, class _Duration>
1966cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1967cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
1968cb14a3feSDimitry Andric  }
19690b57cec5SDimitry Andric};
19700b57cec5SDimitry Andric
19710b57cec5SDimitry Andrictemplate <class _Rp>
1972cb14a3feSDimitry Andricshared_future<_Rp&>::~shared_future() {
19730b57cec5SDimitry Andric  if (__state_)
19740b57cec5SDimitry Andric    __state_->__release_shared();
19750b57cec5SDimitry Andric}
19760b57cec5SDimitry Andric
19770b57cec5SDimitry Andrictemplate <class _Rp>
1978cb14a3feSDimitry 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 <>
1988cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI shared_future<void> {
19890b57cec5SDimitry Andric  __assoc_sub_state* __state_;
19900b57cec5SDimitry Andric
19910b57cec5SDimitry Andricpublic:
1992cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1993cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {
1994cb14a3feSDimitry Andric    if (__state_)
1995cb14a3feSDimitry Andric      __state_->__add_shared();
1996cb14a3feSDimitry Andric  }
1997cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1998cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1999cb14a3feSDimitry Andric    __rhs.__state_ = nullptr;
2000cb14a3feSDimitry Andric  }
20010b57cec5SDimitry Andric  ~shared_future();
20020b57cec5SDimitry Andric  shared_future& operator=(const shared_future& __rhs);
2003cb14a3feSDimitry 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
2009cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void get() const { __state_->copy(); }
20100b57cec5SDimitry Andric
2011cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
20120b57cec5SDimitry Andric
20130b57cec5SDimitry Andric  // functions to check state
2014cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
20150b57cec5SDimitry Andric
2016cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
20170b57cec5SDimitry Andric  template <class _Rep, class _Period>
2018cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
2019cb14a3feSDimitry Andric    return __state_->wait_for(__rel_time);
2020cb14a3feSDimitry Andric  }
20210b57cec5SDimitry Andric  template <class _Clock, class _Duration>
2022cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
2023cb14a3feSDimitry Andric    return __state_->wait_until(__abs_time);
2024cb14a3feSDimitry Andric  }
20250b57cec5SDimitry Andric};
20260b57cec5SDimitry Andric
20270b57cec5SDimitry Andrictemplate <class _Rp>
2028cb14a3feSDimitry 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>
2033cb14a3feSDimitry 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>
2038cb14a3feSDimitry Andricinline shared_future<_Rp&> future<_Rp&>::share() _NOEXCEPT {
20395f757f3fSDimitry Andric  return shared_future<_Rp&>(std::move(*this));
20400b57cec5SDimitry Andric}
20410b57cec5SDimitry Andric
2042cb14a3feSDimitry 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
2046b3edf446SDimitry Andric_LIBCPP_POP_MACROS
2047b3edf446SDimitry Andric
2048*0fca6ea1SDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_THREADS)
2049*0fca6ea1SDimitry Andric
2050bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
2051bdd1243dSDimitry Andric#  include <chrono>
2052bdd1243dSDimitry Andric#endif
2053bdd1243dSDimitry Andric
205406c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
205506c3fb27SDimitry Andric#  include <atomic>
205606c3fb27SDimitry Andric#  include <cstdlib>
205706c3fb27SDimitry Andric#  include <exception>
20585f757f3fSDimitry Andric#  include <iosfwd>
205906c3fb27SDimitry Andric#  include <system_error>
206006c3fb27SDimitry Andric#endif
206106c3fb27SDimitry Andric
20620b57cec5SDimitry Andric#endif // _LIBCPP_FUTURE
2063