xref: /freebsd/contrib/llvm-project/libcxx/include/future (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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
47*5f757f3fSDimitry Andricclass future_error : public logic_error {
480b57cec5SDimitry Andricpublic:
49*5f757f3fSDimitry Andric    explicit future_error(future_errc e); // since C++17
50*5f757f3fSDimitry Andric
510b57cec5SDimitry Andric    const error_code& code() const noexcept;
520b57cec5SDimitry Andric    const char*       what() const noexcept;
53*5f757f3fSDimitry Andric
54*5f757f3fSDimitry Andricprivate:
55*5f757f3fSDimitry Andric    error_code ec_;             // exposition only
560b57cec5SDimitry Andric};
570b57cec5SDimitry Andric
580b57cec5SDimitry Andrictemplate <class R>
590b57cec5SDimitry Andricclass promise
600b57cec5SDimitry Andric{
610b57cec5SDimitry Andricpublic:
620b57cec5SDimitry Andric    promise();
630b57cec5SDimitry Andric    template <class Allocator>
640b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
650b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
660b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
670b57cec5SDimitry Andric    ~promise();
680b57cec5SDimitry Andric
690b57cec5SDimitry Andric    // assignment
700b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
710b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
720b57cec5SDimitry Andric    void swap(promise& other) noexcept;
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric    // retrieving the result
750b57cec5SDimitry Andric    future<R> get_future();
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric    // setting the result
780b57cec5SDimitry Andric    void set_value(const R& r);
790b57cec5SDimitry Andric    void set_value(R&& r);
800b57cec5SDimitry Andric    void set_exception(exception_ptr p);
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric    // setting the result with deferred notification
830b57cec5SDimitry Andric    void set_value_at_thread_exit(const R& r);
840b57cec5SDimitry Andric    void set_value_at_thread_exit(R&& r);
850b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
860b57cec5SDimitry Andric};
870b57cec5SDimitry Andric
880b57cec5SDimitry Andrictemplate <class R>
890b57cec5SDimitry Andricclass promise<R&>
900b57cec5SDimitry Andric{
910b57cec5SDimitry Andricpublic:
920b57cec5SDimitry Andric    promise();
930b57cec5SDimitry Andric    template <class Allocator>
940b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
950b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
960b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
970b57cec5SDimitry Andric    ~promise();
980b57cec5SDimitry Andric
990b57cec5SDimitry Andric    // assignment
1000b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
1010b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
1020b57cec5SDimitry Andric    void swap(promise& other) noexcept;
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andric    // retrieving the result
1050b57cec5SDimitry Andric    future<R&> get_future();
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric    // setting the result
1080b57cec5SDimitry Andric    void set_value(R& r);
1090b57cec5SDimitry Andric    void set_exception(exception_ptr p);
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andric    // setting the result with deferred notification
1120b57cec5SDimitry Andric    void set_value_at_thread_exit(R&);
1130b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
1140b57cec5SDimitry Andric};
1150b57cec5SDimitry Andric
1160b57cec5SDimitry Andrictemplate <>
1170b57cec5SDimitry Andricclass promise<void>
1180b57cec5SDimitry Andric{
1190b57cec5SDimitry Andricpublic:
1200b57cec5SDimitry Andric    promise();
1210b57cec5SDimitry Andric    template <class Allocator>
1220b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
1230b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
1240b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
1250b57cec5SDimitry Andric    ~promise();
1260b57cec5SDimitry Andric
1270b57cec5SDimitry Andric    // assignment
1280b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
1290b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
1300b57cec5SDimitry Andric    void swap(promise& other) noexcept;
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric    // retrieving the result
1330b57cec5SDimitry Andric    future<void> get_future();
1340b57cec5SDimitry Andric
1350b57cec5SDimitry Andric    // setting the result
1360b57cec5SDimitry Andric    void set_value();
1370b57cec5SDimitry Andric    void set_exception(exception_ptr p);
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andric    // setting the result with deferred notification
1400b57cec5SDimitry Andric    void set_value_at_thread_exit();
1410b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
1420b57cec5SDimitry Andric};
1430b57cec5SDimitry Andric
1440b57cec5SDimitry Andrictemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andrictemplate <class R, class Alloc>
1470b57cec5SDimitry Andric    struct uses_allocator<promise<R>, Alloc> : public true_type {};
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andrictemplate <class R>
1500b57cec5SDimitry Andricclass future
1510b57cec5SDimitry Andric{
1520b57cec5SDimitry Andricpublic:
1530b57cec5SDimitry Andric    future() noexcept;
1540b57cec5SDimitry Andric    future(future&&) noexcept;
1550b57cec5SDimitry Andric    future(const future& rhs) = delete;
1560b57cec5SDimitry Andric    ~future();
1570b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
1580b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
1590b57cec5SDimitry Andric    shared_future<R> share() noexcept;
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric    // retrieving the value
1620b57cec5SDimitry Andric    R get();
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric    // functions to check state
1650b57cec5SDimitry Andric    bool valid() const noexcept;
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andric    void wait() const;
1680b57cec5SDimitry Andric    template <class Rep, class Period>
1690b57cec5SDimitry Andric        future_status
1700b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
1710b57cec5SDimitry Andric    template <class Clock, class Duration>
1720b57cec5SDimitry Andric        future_status
1730b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
1740b57cec5SDimitry Andric};
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andrictemplate <class R>
1770b57cec5SDimitry Andricclass future<R&>
1780b57cec5SDimitry Andric{
1790b57cec5SDimitry Andricpublic:
1800b57cec5SDimitry Andric    future() noexcept;
1810b57cec5SDimitry Andric    future(future&&) noexcept;
1820b57cec5SDimitry Andric    future(const future& rhs) = delete;
1830b57cec5SDimitry Andric    ~future();
1840b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
1850b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
1860b57cec5SDimitry Andric    shared_future<R&> share() noexcept;
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andric    // retrieving the value
1890b57cec5SDimitry Andric    R& get();
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andric    // functions to check state
1920b57cec5SDimitry Andric    bool valid() const noexcept;
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric    void wait() const;
1950b57cec5SDimitry Andric    template <class Rep, class Period>
1960b57cec5SDimitry Andric        future_status
1970b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
1980b57cec5SDimitry Andric    template <class Clock, class Duration>
1990b57cec5SDimitry Andric        future_status
2000b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2010b57cec5SDimitry Andric};
2020b57cec5SDimitry Andric
2030b57cec5SDimitry Andrictemplate <>
2040b57cec5SDimitry Andricclass future<void>
2050b57cec5SDimitry Andric{
2060b57cec5SDimitry Andricpublic:
2070b57cec5SDimitry Andric    future() noexcept;
2080b57cec5SDimitry Andric    future(future&&) noexcept;
2090b57cec5SDimitry Andric    future(const future& rhs) = delete;
2100b57cec5SDimitry Andric    ~future();
2110b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
2120b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
2130b57cec5SDimitry Andric    shared_future<void> share() noexcept;
2140b57cec5SDimitry Andric
2150b57cec5SDimitry Andric    // retrieving the value
2160b57cec5SDimitry Andric    void get();
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric    // functions to check state
2190b57cec5SDimitry Andric    bool valid() const noexcept;
2200b57cec5SDimitry Andric
2210b57cec5SDimitry Andric    void wait() const;
2220b57cec5SDimitry Andric    template <class Rep, class Period>
2230b57cec5SDimitry Andric        future_status
2240b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2250b57cec5SDimitry Andric    template <class Clock, class Duration>
2260b57cec5SDimitry Andric        future_status
2270b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2280b57cec5SDimitry Andric};
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andrictemplate <class R>
2310b57cec5SDimitry Andricclass shared_future
2320b57cec5SDimitry Andric{
2330b57cec5SDimitry Andricpublic:
2340b57cec5SDimitry Andric    shared_future() noexcept;
2350b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2360b57cec5SDimitry Andric    shared_future(future<R>&&) noexcept;
2370b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2380b57cec5SDimitry Andric    ~shared_future();
2390b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2400b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andric    // retrieving the value
2430b57cec5SDimitry Andric    const R& get() const;
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric    // functions to check state
2460b57cec5SDimitry Andric    bool valid() const noexcept;
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andric    void wait() const;
2490b57cec5SDimitry Andric    template <class Rep, class Period>
2500b57cec5SDimitry Andric        future_status
2510b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2520b57cec5SDimitry Andric    template <class Clock, class Duration>
2530b57cec5SDimitry Andric        future_status
2540b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2550b57cec5SDimitry Andric};
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andrictemplate <class R>
2580b57cec5SDimitry Andricclass shared_future<R&>
2590b57cec5SDimitry Andric{
2600b57cec5SDimitry Andricpublic:
2610b57cec5SDimitry Andric    shared_future() noexcept;
2620b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2630b57cec5SDimitry Andric    shared_future(future<R&>&&) noexcept;
2640b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2650b57cec5SDimitry Andric    ~shared_future();
2660b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2670b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric    // retrieving the value
2700b57cec5SDimitry Andric    R& get() const;
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andric    // functions to check state
2730b57cec5SDimitry Andric    bool valid() const noexcept;
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andric    void wait() const;
2760b57cec5SDimitry Andric    template <class Rep, class Period>
2770b57cec5SDimitry Andric        future_status
2780b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2790b57cec5SDimitry Andric    template <class Clock, class Duration>
2800b57cec5SDimitry Andric        future_status
2810b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2820b57cec5SDimitry Andric};
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andrictemplate <>
2850b57cec5SDimitry Andricclass shared_future<void>
2860b57cec5SDimitry Andric{
2870b57cec5SDimitry Andricpublic:
2880b57cec5SDimitry Andric    shared_future() noexcept;
2890b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
2900b57cec5SDimitry Andric    shared_future(future<void>&&) noexcept;
2910b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2920b57cec5SDimitry Andric    ~shared_future();
2930b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
2940b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andric    // retrieving the value
2970b57cec5SDimitry Andric    void get() const;
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric    // functions to check state
3000b57cec5SDimitry Andric    bool valid() const noexcept;
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andric    void wait() const;
3030b57cec5SDimitry Andric    template <class Rep, class Period>
3040b57cec5SDimitry Andric        future_status
3050b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
3060b57cec5SDimitry Andric    template <class Clock, class Duration>
3070b57cec5SDimitry Andric        future_status
3080b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
3090b57cec5SDimitry Andric};
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andrictemplate <class F, class... Args>
3120b57cec5SDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
3130b57cec5SDimitry Andric  async(F&& f, Args&&... args);
3140b57cec5SDimitry Andric
3150b57cec5SDimitry Andrictemplate <class F, class... Args>
3160b57cec5SDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
3170b57cec5SDimitry Andric  async(launch policy, F&& f, Args&&... args);
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andrictemplate <class> class packaged_task; // undefined
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andrictemplate <class R, class... ArgTypes>
3220b57cec5SDimitry Andricclass packaged_task<R(ArgTypes...)>
3230b57cec5SDimitry Andric{
3240b57cec5SDimitry Andricpublic:
3250b57cec5SDimitry Andric    typedef R result_type; // extension
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric    // construction and destruction
3280b57cec5SDimitry Andric    packaged_task() noexcept;
3290b57cec5SDimitry Andric    template <class F>
3300b57cec5SDimitry Andric        explicit packaged_task(F&& f);
3310b57cec5SDimitry Andric    template <class F, class Allocator>
3320b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const Allocator& a, F&& f);
3330b57cec5SDimitry Andric    ~packaged_task();
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric    // no copy
3360b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
3370b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andric    // move support
3400b57cec5SDimitry Andric    packaged_task(packaged_task&& other) noexcept;
3410b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& other) noexcept;
3420b57cec5SDimitry Andric    void swap(packaged_task& other) noexcept;
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andric    bool valid() const noexcept;
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andric    // result retrieval
3470b57cec5SDimitry Andric    future<R> get_future();
3480b57cec5SDimitry Andric
3490b57cec5SDimitry Andric    // execution
3500b57cec5SDimitry Andric    void operator()(ArgTypes... );
3510b57cec5SDimitry Andric    void make_ready_at_thread_exit(ArgTypes...);
3520b57cec5SDimitry Andric
3530b57cec5SDimitry Andric    void reset();
3540b57cec5SDimitry Andric};
3550b57cec5SDimitry Andric
3560b57cec5SDimitry Andrictemplate <class R>
3570b57cec5SDimitry Andric  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andrictemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
3600b57cec5SDimitry Andric
3610b57cec5SDimitry Andric}  // std
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andric*/
3640b57cec5SDimitry Andric
36581ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
366e8d8bef9SDimitry Andric#include <__availability>
36781ad6265SDimitry Andric#include <__chrono/duration.h>
36881ad6265SDimitry Andric#include <__chrono/time_point.h>
369fe6060f1SDimitry Andric#include <__config>
37006c3fb27SDimitry Andric#include <__exception/exception_ptr.h>
37106c3fb27SDimitry Andric#include <__memory/addressof.h>
37206c3fb27SDimitry Andric#include <__memory/allocator.h>
373fe6060f1SDimitry Andric#include <__memory/allocator_arg_t.h>
374bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h>
37506c3fb27SDimitry Andric#include <__memory/allocator_traits.h>
37606c3fb27SDimitry Andric#include <__memory/compressed_pair.h>
37706c3fb27SDimitry Andric#include <__memory/pointer_traits.h>
37806c3fb27SDimitry Andric#include <__memory/shared_ptr.h>
37906c3fb27SDimitry Andric#include <__memory/unique_ptr.h>
380fe6060f1SDimitry Andric#include <__memory/uses_allocator.h>
38106c3fb27SDimitry Andric#include <__system_error/error_category.h>
38206c3fb27SDimitry Andric#include <__system_error/error_code.h>
38306c3fb27SDimitry Andric#include <__system_error/error_condition.h>
38406c3fb27SDimitry Andric#include <__type_traits/aligned_storage.h>
385bdd1243dSDimitry Andric#include <__type_traits/strip_signature.h>
3860eae32dcSDimitry Andric#include <__utility/auto_cast.h>
387fe6060f1SDimitry Andric#include <__utility/forward.h>
38881ad6265SDimitry Andric#include <__utility/move.h>
3890b57cec5SDimitry Andric#include <mutex>
390bdd1243dSDimitry Andric#include <new>
39106c3fb27SDimitry Andric#include <stdexcept>
3920b57cec5SDimitry Andric#include <thread>
39304eeddc0SDimitry Andric#include <version>
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3960b57cec5SDimitry Andric#  pragma GCC system_header
3970b57cec5SDimitry Andric#endif
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
40081ad6265SDimitry Andric# error "<future> is not supported since libc++ has been configured without support for threads."
40181ad6265SDimitry Andric#endif
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric//enum class future_errc
4060b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
4070b57cec5SDimitry Andric{
4080b57cec5SDimitry Andric    future_already_retrieved = 1,
4090b57cec5SDimitry Andric    promise_already_satisfied,
4100b57cec5SDimitry Andric    no_state,
4110b57cec5SDimitry Andric    broken_promise
4120b57cec5SDimitry Andric};
4130b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
4140b57cec5SDimitry Andric
4150b57cec5SDimitry Andrictemplate <>
4160b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
4170b57cec5SDimitry Andric
41881ad6265SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
4190b57cec5SDimitry Andrictemplate <>
4200b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
4210b57cec5SDimitry Andric#endif
4220b57cec5SDimitry Andric
4230b57cec5SDimitry Andric//enum class launch
4240b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(launch)
4250b57cec5SDimitry Andric{
4260b57cec5SDimitry Andric    async = 1,
4270b57cec5SDimitry Andric    deferred = 2,
4280b57cec5SDimitry Andric    any = async | deferred
4290b57cec5SDimitry Andric};
4300b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
4310b57cec5SDimitry Andric
43281ad6265SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
4330b57cec5SDimitry Andric
4340b57cec5SDimitry Andrictypedef underlying_type<launch>::type __launch_underlying_type;
4350b57cec5SDimitry Andric
436*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
4370b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
4380b57cec5SDimitry Andriclaunch
4390b57cec5SDimitry Andricoperator&(launch __x, launch __y)
4400b57cec5SDimitry Andric{
4410b57cec5SDimitry Andric    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
4420b57cec5SDimitry Andric                               static_cast<__launch_underlying_type>(__y));
4430b57cec5SDimitry Andric}
4440b57cec5SDimitry Andric
445*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
4460b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
4470b57cec5SDimitry Andriclaunch
4480b57cec5SDimitry Andricoperator|(launch __x, launch __y)
4490b57cec5SDimitry Andric{
4500b57cec5SDimitry Andric    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
4510b57cec5SDimitry Andric                               static_cast<__launch_underlying_type>(__y));
4520b57cec5SDimitry Andric}
4530b57cec5SDimitry Andric
454*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
4550b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
4560b57cec5SDimitry Andriclaunch
4570b57cec5SDimitry Andricoperator^(launch __x, launch __y)
4580b57cec5SDimitry Andric{
4590b57cec5SDimitry Andric    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
4600b57cec5SDimitry Andric                               static_cast<__launch_underlying_type>(__y));
4610b57cec5SDimitry Andric}
4620b57cec5SDimitry Andric
463*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
4640b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
4650b57cec5SDimitry Andriclaunch
4660b57cec5SDimitry Andricoperator~(launch __x)
4670b57cec5SDimitry Andric{
4680b57cec5SDimitry Andric    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
4690b57cec5SDimitry Andric}
4700b57cec5SDimitry Andric
471*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
4720b57cec5SDimitry Andriclaunch&
4730b57cec5SDimitry Andricoperator&=(launch& __x, launch __y)
4740b57cec5SDimitry Andric{
4750b57cec5SDimitry Andric    __x = __x & __y; return __x;
4760b57cec5SDimitry Andric}
4770b57cec5SDimitry Andric
478*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
4790b57cec5SDimitry Andriclaunch&
4800b57cec5SDimitry Andricoperator|=(launch& __x, launch __y)
4810b57cec5SDimitry Andric{
4820b57cec5SDimitry Andric    __x = __x | __y; return __x;
4830b57cec5SDimitry Andric}
4840b57cec5SDimitry Andric
485*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
4860b57cec5SDimitry Andriclaunch&
4870b57cec5SDimitry Andricoperator^=(launch& __x, launch __y)
4880b57cec5SDimitry Andric{
4890b57cec5SDimitry Andric    __x = __x ^ __y; return __x;
4900b57cec5SDimitry Andric}
4910b57cec5SDimitry Andric
49281ad6265SDimitry Andric#endif // !_LIBCPP_CXX03_LANG
4930b57cec5SDimitry Andric
4940b57cec5SDimitry Andric//enum class future_status
4950b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_status)
4960b57cec5SDimitry Andric{
4970b57cec5SDimitry Andric    ready,
4980b57cec5SDimitry Andric    timeout,
4990b57cec5SDimitry Andric    deferred
5000b57cec5SDimitry Andric};
5010b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
5020b57cec5SDimitry Andric
50306c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;
5040b57cec5SDimitry Andric
505*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
5060b57cec5SDimitry Andricerror_code
5070b57cec5SDimitry Andricmake_error_code(future_errc __e) _NOEXCEPT
5080b57cec5SDimitry Andric{
5090b57cec5SDimitry Andric    return error_code(static_cast<int>(__e), future_category());
5100b57cec5SDimitry Andric}
5110b57cec5SDimitry Andric
512*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
5130b57cec5SDimitry Andricerror_condition
5140b57cec5SDimitry Andricmake_error_condition(future_errc __e) _NOEXCEPT
5150b57cec5SDimitry Andric{
5160b57cec5SDimitry Andric    return error_condition(static_cast<int>(__e), future_category());
5170b57cec5SDimitry Andric}
5180b57cec5SDimitry Andric
519*5f757f3fSDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_future_error(future_errc __ev);
520fe6060f1SDimitry Andric
521*5f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future_error : public logic_error {
522*5f757f3fSDimitry Andric    error_code __ec_;
523*5f757f3fSDimitry Andric
524*5f757f3fSDimitry Andric    future_error(error_code);
525*5f757f3fSDimitry Andric    friend void __throw_future_error(future_errc);
526*5f757f3fSDimitry Andric    template <class> friend class promise;
527*5f757f3fSDimitry Andric
528*5f757f3fSDimitry Andricpublic:
529*5f757f3fSDimitry Andric#if _LIBCPP_STD_VER >= 17
530*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI explicit future_error(future_errc __ec) : future_error(std::make_error_code(__ec)) {}
531*5f757f3fSDimitry Andric#endif
532*5f757f3fSDimitry Andric
533*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5340b57cec5SDimitry Andric    const error_code& code() const _NOEXCEPT {return __ec_;}
5350b57cec5SDimitry Andric
53606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default;
537bdd1243dSDimitry Andric    ~future_error() _NOEXCEPT override;
5380b57cec5SDimitry Andric};
5390b57cec5SDimitry Andric
540*5f757f3fSDimitry Andric// Declared above std::future_error
541753f127fSDimitry Andricvoid __throw_future_error(future_errc __ev)
5420b57cec5SDimitry Andric{
54306c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
544753f127fSDimitry Andric    throw future_error(make_error_code(__ev));
5450b57cec5SDimitry Andric#else
54606c3fb27SDimitry Andric    (void)__ev;
54706c3fb27SDimitry Andric    _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode");
5480b57cec5SDimitry Andric#endif
5490b57cec5SDimitry Andric}
5500b57cec5SDimitry Andric
551*5f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI __assoc_sub_state : public __shared_count {
5520b57cec5SDimitry Andricprotected:
5530b57cec5SDimitry Andric    exception_ptr __exception_;
5540b57cec5SDimitry Andric    mutable mutex __mut_;
5550b57cec5SDimitry Andric    mutable condition_variable __cv_;
5560b57cec5SDimitry Andric    unsigned __state_;
5570b57cec5SDimitry Andric
558bdd1243dSDimitry Andric    void __on_zero_shared() _NOEXCEPT override;
5590b57cec5SDimitry Andric    void __sub_wait(unique_lock<mutex>& __lk);
5600b57cec5SDimitry Andricpublic:
5610b57cec5SDimitry Andric    enum
5620b57cec5SDimitry Andric    {
5630b57cec5SDimitry Andric        __constructed = 1,
5640b57cec5SDimitry Andric        __future_attached = 2,
5650b57cec5SDimitry Andric        ready = 4,
5660b57cec5SDimitry Andric        deferred = 8
5670b57cec5SDimitry Andric    };
5680b57cec5SDimitry Andric
569*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5700b57cec5SDimitry Andric    __assoc_sub_state() : __state_(0) {}
5710b57cec5SDimitry Andric
572*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5730b57cec5SDimitry Andric    bool __has_value() const
5740b57cec5SDimitry Andric        {return (__state_ & __constructed) || (__exception_ != nullptr);}
5750b57cec5SDimitry Andric
576*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5770b57cec5SDimitry Andric    void __attach_future() {
5780b57cec5SDimitry Andric        lock_guard<mutex> __lk(__mut_);
5790b57cec5SDimitry Andric        bool __has_future_attached = (__state_ & __future_attached) != 0;
5800b57cec5SDimitry Andric        if (__has_future_attached)
5810b57cec5SDimitry Andric            __throw_future_error(future_errc::future_already_retrieved);
5820b57cec5SDimitry Andric        this->__add_shared();
5830b57cec5SDimitry Andric        __state_ |= __future_attached;
5840b57cec5SDimitry Andric    }
5850b57cec5SDimitry Andric
586*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5870b57cec5SDimitry Andric    void __set_deferred() {__state_ |= deferred;}
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andric    void __make_ready();
590*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5910b57cec5SDimitry Andric    bool __is_ready() const {return (__state_ & ready) != 0;}
5920b57cec5SDimitry Andric
5930b57cec5SDimitry Andric    void set_value();
5940b57cec5SDimitry Andric    void set_value_at_thread_exit();
5950b57cec5SDimitry Andric
5960b57cec5SDimitry Andric    void set_exception(exception_ptr __p);
5970b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr __p);
5980b57cec5SDimitry Andric
5990b57cec5SDimitry Andric    void copy();
6000b57cec5SDimitry Andric
6010b57cec5SDimitry Andric    void wait();
6020b57cec5SDimitry Andric    template <class _Rep, class _Period>
6030b57cec5SDimitry Andric        future_status
604*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
6050b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
6060b57cec5SDimitry Andric    template <class _Clock, class _Duration>
6070b57cec5SDimitry Andric        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
6080b57cec5SDimitry Andric        future_status
6090b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
6100b57cec5SDimitry Andric
6110b57cec5SDimitry Andric    virtual void __execute();
6120b57cec5SDimitry Andric};
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andrictemplate <class _Clock, class _Duration>
6150b57cec5SDimitry Andricfuture_status
6160b57cec5SDimitry Andric__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
6170b57cec5SDimitry Andric{
6180b57cec5SDimitry Andric    unique_lock<mutex> __lk(__mut_);
6190b57cec5SDimitry Andric    if (__state_ & deferred)
6200b57cec5SDimitry Andric        return future_status::deferred;
6210b57cec5SDimitry Andric    while (!(__state_ & ready) && _Clock::now() < __abs_time)
6220b57cec5SDimitry Andric        __cv_.wait_until(__lk, __abs_time);
6230b57cec5SDimitry Andric    if (__state_ & ready)
6240b57cec5SDimitry Andric        return future_status::ready;
6250b57cec5SDimitry Andric    return future_status::timeout;
6260b57cec5SDimitry Andric}
6270b57cec5SDimitry Andric
6280b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
6290b57cec5SDimitry Andricinline
6300b57cec5SDimitry Andricfuture_status
6310b57cec5SDimitry Andric__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
6320b57cec5SDimitry Andric{
6330b57cec5SDimitry Andric    return wait_until(chrono::steady_clock::now() + __rel_time);
6340b57cec5SDimitry Andric}
6350b57cec5SDimitry Andric
6360b57cec5SDimitry Andrictemplate <class _Rp>
637*5f757f3fSDimitry Andricclass _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state
6380b57cec5SDimitry Andric{
6390b57cec5SDimitry Andric    typedef __assoc_sub_state base;
640bdd1243dSDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH
641*5f757f3fSDimitry Andric    typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up;
642bdd1243dSDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_POP
6430b57cec5SDimitry Andricprotected:
6440b57cec5SDimitry Andric    _Up __value_;
6450b57cec5SDimitry Andric
64606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
6470b57cec5SDimitry Andricpublic:
6480b57cec5SDimitry Andric
6490b57cec5SDimitry Andric    template <class _Arg>
65006c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg);
6510b57cec5SDimitry Andric
6520b57cec5SDimitry Andric    template <class _Arg>
65306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg);
6540b57cec5SDimitry Andric
65506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI _Rp move();
65606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy();
6570b57cec5SDimitry Andric};
6580b57cec5SDimitry Andric
6590b57cec5SDimitry Andrictemplate <class _Rp>
6600b57cec5SDimitry Andricvoid
6610b57cec5SDimitry Andric__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
6620b57cec5SDimitry Andric{
6630b57cec5SDimitry Andric    if (this->__state_ & base::__constructed)
6640b57cec5SDimitry Andric        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
6650b57cec5SDimitry Andric    delete this;
6660b57cec5SDimitry Andric}
6670b57cec5SDimitry Andric
6680b57cec5SDimitry Andrictemplate <class _Rp>
6690b57cec5SDimitry Andrictemplate <class _Arg>
6700b57cec5SDimitry Andricvoid
6710b57cec5SDimitry Andric__assoc_state<_Rp>::set_value(_Arg&& __arg)
6720b57cec5SDimitry Andric{
6730b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
6740b57cec5SDimitry Andric    if (this->__has_value())
6750b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
676*5f757f3fSDimitry Andric    ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
6770b57cec5SDimitry Andric    this->__state_ |= base::__constructed | base::ready;
6780b57cec5SDimitry Andric    __cv_.notify_all();
6790b57cec5SDimitry Andric}
6800b57cec5SDimitry Andric
6810b57cec5SDimitry Andrictemplate <class _Rp>
6820b57cec5SDimitry Andrictemplate <class _Arg>
6830b57cec5SDimitry Andricvoid
6840b57cec5SDimitry Andric__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
6850b57cec5SDimitry Andric{
6860b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
6870b57cec5SDimitry Andric    if (this->__has_value())
6880b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
689*5f757f3fSDimitry Andric    ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
6900b57cec5SDimitry Andric    this->__state_ |= base::__constructed;
6910b57cec5SDimitry Andric    __thread_local_data()->__make_ready_at_thread_exit(this);
6920b57cec5SDimitry Andric}
6930b57cec5SDimitry Andric
6940b57cec5SDimitry Andrictemplate <class _Rp>
6950b57cec5SDimitry Andric_Rp
6960b57cec5SDimitry Andric__assoc_state<_Rp>::move()
6970b57cec5SDimitry Andric{
6980b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
6990b57cec5SDimitry Andric    this->__sub_wait(__lk);
7000b57cec5SDimitry Andric    if (this->__exception_ != nullptr)
701bdd1243dSDimitry Andric        std::rethrow_exception(this->__exception_);
702*5f757f3fSDimitry Andric    return std::move(*reinterpret_cast<_Rp*>(&__value_));
7030b57cec5SDimitry Andric}
7040b57cec5SDimitry Andric
7050b57cec5SDimitry Andrictemplate <class _Rp>
706bdd1243dSDimitry Andric__add_lvalue_reference_t<_Rp>
7070b57cec5SDimitry Andric__assoc_state<_Rp>::copy()
7080b57cec5SDimitry Andric{
7090b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
7100b57cec5SDimitry Andric    this->__sub_wait(__lk);
7110b57cec5SDimitry Andric    if (this->__exception_ != nullptr)
712bdd1243dSDimitry Andric        std::rethrow_exception(this->__exception_);
7130b57cec5SDimitry Andric    return *reinterpret_cast<_Rp*>(&__value_);
7140b57cec5SDimitry Andric}
7150b57cec5SDimitry Andric
7160b57cec5SDimitry Andrictemplate <class _Rp>
717*5f757f3fSDimitry Andricclass __assoc_state<_Rp&> : public __assoc_sub_state
7180b57cec5SDimitry Andric{
7190b57cec5SDimitry Andric    typedef __assoc_sub_state base;
7200b57cec5SDimitry Andric    typedef _Rp* _Up;
7210b57cec5SDimitry Andricprotected:
7220b57cec5SDimitry Andric    _Up __value_;
7230b57cec5SDimitry Andric
72406c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
7250b57cec5SDimitry Andricpublic:
7260b57cec5SDimitry Andric
72706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg);
72806c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg);
7290b57cec5SDimitry Andric
73006c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI _Rp& copy();
7310b57cec5SDimitry Andric};
7320b57cec5SDimitry Andric
7330b57cec5SDimitry Andrictemplate <class _Rp>
7340b57cec5SDimitry Andricvoid
7350b57cec5SDimitry Andric__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
7360b57cec5SDimitry Andric{
7370b57cec5SDimitry Andric    delete this;
7380b57cec5SDimitry Andric}
7390b57cec5SDimitry Andric
7400b57cec5SDimitry Andrictemplate <class _Rp>
7410b57cec5SDimitry Andricvoid
7420b57cec5SDimitry Andric__assoc_state<_Rp&>::set_value(_Rp& __arg)
7430b57cec5SDimitry Andric{
7440b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
7450b57cec5SDimitry Andric    if (this->__has_value())
7460b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
747*5f757f3fSDimitry Andric    __value_ = std::addressof(__arg);
7480b57cec5SDimitry Andric    this->__state_ |= base::__constructed | base::ready;
7490b57cec5SDimitry Andric    __cv_.notify_all();
7500b57cec5SDimitry Andric}
7510b57cec5SDimitry Andric
7520b57cec5SDimitry Andrictemplate <class _Rp>
7530b57cec5SDimitry Andricvoid
7540b57cec5SDimitry Andric__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
7550b57cec5SDimitry Andric{
7560b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
7570b57cec5SDimitry Andric    if (this->__has_value())
7580b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
759*5f757f3fSDimitry Andric    __value_ = std::addressof(__arg);
7600b57cec5SDimitry Andric    this->__state_ |= base::__constructed;
7610b57cec5SDimitry Andric    __thread_local_data()->__make_ready_at_thread_exit(this);
7620b57cec5SDimitry Andric}
7630b57cec5SDimitry Andric
7640b57cec5SDimitry Andrictemplate <class _Rp>
7650b57cec5SDimitry Andric_Rp&
7660b57cec5SDimitry Andric__assoc_state<_Rp&>::copy()
7670b57cec5SDimitry Andric{
7680b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
7690b57cec5SDimitry Andric    this->__sub_wait(__lk);
7700b57cec5SDimitry Andric    if (this->__exception_ != nullptr)
771bdd1243dSDimitry Andric        std::rethrow_exception(this->__exception_);
7720b57cec5SDimitry Andric    return *__value_;
7730b57cec5SDimitry Andric}
7740b57cec5SDimitry Andric
7750b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
776*5f757f3fSDimitry Andricclass __assoc_state_alloc : public __assoc_state<_Rp>
7770b57cec5SDimitry Andric{
7780b57cec5SDimitry Andric    typedef __assoc_state<_Rp> base;
7790b57cec5SDimitry Andric    _Alloc __alloc_;
7800b57cec5SDimitry Andric
78106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
7820b57cec5SDimitry Andricpublic:
783*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
7840b57cec5SDimitry Andric    explicit __assoc_state_alloc(const _Alloc& __a)
7850b57cec5SDimitry Andric        : __alloc_(__a) {}
7860b57cec5SDimitry Andric};
7870b57cec5SDimitry Andric
7880b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
7890b57cec5SDimitry Andricvoid
7900b57cec5SDimitry Andric__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
7910b57cec5SDimitry Andric{
7920b57cec5SDimitry Andric    if (this->__state_ & base::__constructed)
793*5f757f3fSDimitry Andric        reinterpret_cast<_Rp*>(std::addressof(this->__value_))->~_Rp();
7940b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
7950b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
7960b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
7970b57cec5SDimitry Andric    _Al __a(__alloc_);
7980b57cec5SDimitry Andric    this->~__assoc_state_alloc();
7990b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
8000b57cec5SDimitry Andric}
8010b57cec5SDimitry Andric
8020b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
803*5f757f3fSDimitry Andricclass __assoc_state_alloc<_Rp&, _Alloc> : public __assoc_state<_Rp&>
8040b57cec5SDimitry Andric{
8050b57cec5SDimitry Andric    typedef __assoc_state<_Rp&> base;
8060b57cec5SDimitry Andric    _Alloc __alloc_;
8070b57cec5SDimitry Andric
80806c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
8090b57cec5SDimitry Andricpublic:
810*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8110b57cec5SDimitry Andric    explicit __assoc_state_alloc(const _Alloc& __a)
8120b57cec5SDimitry Andric        : __alloc_(__a) {}
8130b57cec5SDimitry Andric};
8140b57cec5SDimitry Andric
8150b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
8160b57cec5SDimitry Andricvoid
8170b57cec5SDimitry Andric__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
8180b57cec5SDimitry Andric{
8190b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
8200b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
8210b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
8220b57cec5SDimitry Andric    _Al __a(__alloc_);
8230b57cec5SDimitry Andric    this->~__assoc_state_alloc();
8240b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
8250b57cec5SDimitry Andric}
8260b57cec5SDimitry Andric
8270b57cec5SDimitry Andrictemplate <class _Alloc>
828*5f757f3fSDimitry Andricclass __assoc_sub_state_alloc : public __assoc_sub_state
8290b57cec5SDimitry Andric{
8300b57cec5SDimitry Andric    typedef __assoc_sub_state base;
8310b57cec5SDimitry Andric    _Alloc __alloc_;
8320b57cec5SDimitry Andric
83306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
8340b57cec5SDimitry Andricpublic:
835*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8360b57cec5SDimitry Andric    explicit __assoc_sub_state_alloc(const _Alloc& __a)
8370b57cec5SDimitry Andric        : __alloc_(__a) {}
8380b57cec5SDimitry Andric};
8390b57cec5SDimitry Andric
8400b57cec5SDimitry Andrictemplate <class _Alloc>
8410b57cec5SDimitry Andricvoid
8420b57cec5SDimitry Andric__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
8430b57cec5SDimitry Andric{
8440b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
8450b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
8460b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
8470b57cec5SDimitry Andric    _Al __a(__alloc_);
8480b57cec5SDimitry Andric    this->~__assoc_sub_state_alloc();
8490b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
8500b57cec5SDimitry Andric}
8510b57cec5SDimitry Andric
8520b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
853*5f757f3fSDimitry Andricclass __deferred_assoc_state : public __assoc_state<_Rp>
8540b57cec5SDimitry Andric{
8550b57cec5SDimitry Andric    typedef __assoc_state<_Rp> base;
8560b57cec5SDimitry Andric
8570b57cec5SDimitry Andric    _Fp __func_;
8580b57cec5SDimitry Andric
8590b57cec5SDimitry Andricpublic:
860*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8610b57cec5SDimitry Andric    explicit __deferred_assoc_state(_Fp&& __f);
8620b57cec5SDimitry Andric
86306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
8640b57cec5SDimitry Andric};
8650b57cec5SDimitry Andric
8660b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
8670b57cec5SDimitry Andricinline
8680b57cec5SDimitry Andric__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
869*5f757f3fSDimitry Andric    : __func_(std::forward<_Fp>(__f))
8700b57cec5SDimitry Andric{
8710b57cec5SDimitry Andric    this->__set_deferred();
8720b57cec5SDimitry Andric}
8730b57cec5SDimitry Andric
8740b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
8750b57cec5SDimitry Andricvoid
8760b57cec5SDimitry Andric__deferred_assoc_state<_Rp, _Fp>::__execute()
8770b57cec5SDimitry Andric{
87806c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
8790b57cec5SDimitry Andric    try
8800b57cec5SDimitry Andric    {
88106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8820b57cec5SDimitry Andric        this->set_value(__func_());
88306c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
8840b57cec5SDimitry Andric    }
8850b57cec5SDimitry Andric    catch (...)
8860b57cec5SDimitry Andric    {
8870b57cec5SDimitry Andric        this->set_exception(current_exception());
8880b57cec5SDimitry Andric    }
88906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
8900b57cec5SDimitry Andric}
8910b57cec5SDimitry Andric
8920b57cec5SDimitry Andrictemplate <class _Fp>
893*5f757f3fSDimitry Andricclass __deferred_assoc_state<void, _Fp> : public __assoc_sub_state
8940b57cec5SDimitry Andric{
8950b57cec5SDimitry Andric    typedef __assoc_sub_state base;
8960b57cec5SDimitry Andric
8970b57cec5SDimitry Andric    _Fp __func_;
8980b57cec5SDimitry Andric
8990b57cec5SDimitry Andricpublic:
900*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9010b57cec5SDimitry Andric    explicit __deferred_assoc_state(_Fp&& __f);
9020b57cec5SDimitry Andric
90306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
9040b57cec5SDimitry Andric};
9050b57cec5SDimitry Andric
9060b57cec5SDimitry Andrictemplate <class _Fp>
9070b57cec5SDimitry Andricinline
9080b57cec5SDimitry Andric__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
909*5f757f3fSDimitry Andric    : __func_(std::forward<_Fp>(__f))
9100b57cec5SDimitry Andric{
9110b57cec5SDimitry Andric    this->__set_deferred();
9120b57cec5SDimitry Andric}
9130b57cec5SDimitry Andric
9140b57cec5SDimitry Andrictemplate <class _Fp>
9150b57cec5SDimitry Andricvoid
9160b57cec5SDimitry Andric__deferred_assoc_state<void, _Fp>::__execute()
9170b57cec5SDimitry Andric{
91806c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
9190b57cec5SDimitry Andric    try
9200b57cec5SDimitry Andric    {
92106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
9220b57cec5SDimitry Andric        __func_();
9230b57cec5SDimitry Andric        this->set_value();
92406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
9250b57cec5SDimitry Andric    }
9260b57cec5SDimitry Andric    catch (...)
9270b57cec5SDimitry Andric    {
9280b57cec5SDimitry Andric        this->set_exception(current_exception());
9290b57cec5SDimitry Andric    }
93006c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
9310b57cec5SDimitry Andric}
9320b57cec5SDimitry Andric
9330b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
934*5f757f3fSDimitry Andricclass __async_assoc_state : public __assoc_state<_Rp>
9350b57cec5SDimitry Andric{
9360b57cec5SDimitry Andric    typedef __assoc_state<_Rp> base;
9370b57cec5SDimitry Andric
9380b57cec5SDimitry Andric    _Fp __func_;
9390b57cec5SDimitry Andric
94006c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
9410b57cec5SDimitry Andricpublic:
942*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9430b57cec5SDimitry Andric    explicit __async_assoc_state(_Fp&& __f);
9440b57cec5SDimitry Andric
94506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
9460b57cec5SDimitry Andric};
9470b57cec5SDimitry Andric
9480b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
9490b57cec5SDimitry Andricinline
9500b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
951*5f757f3fSDimitry Andric    : __func_(std::forward<_Fp>(__f))
9520b57cec5SDimitry Andric{
9530b57cec5SDimitry Andric}
9540b57cec5SDimitry Andric
9550b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
9560b57cec5SDimitry Andricvoid
9570b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__execute()
9580b57cec5SDimitry Andric{
95906c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
9600b57cec5SDimitry Andric    try
9610b57cec5SDimitry Andric    {
96206c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
9630b57cec5SDimitry Andric        this->set_value(__func_());
96406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
9650b57cec5SDimitry Andric    }
9660b57cec5SDimitry Andric    catch (...)
9670b57cec5SDimitry Andric    {
9680b57cec5SDimitry Andric        this->set_exception(current_exception());
9690b57cec5SDimitry Andric    }
97006c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
9710b57cec5SDimitry Andric}
9720b57cec5SDimitry Andric
9730b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
9740b57cec5SDimitry Andricvoid
9750b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
9760b57cec5SDimitry Andric{
9770b57cec5SDimitry Andric    this->wait();
9780b57cec5SDimitry Andric    base::__on_zero_shared();
9790b57cec5SDimitry Andric}
9800b57cec5SDimitry Andric
9810b57cec5SDimitry Andrictemplate <class _Fp>
982*5f757f3fSDimitry Andricclass __async_assoc_state<void, _Fp> : public __assoc_sub_state
9830b57cec5SDimitry Andric{
9840b57cec5SDimitry Andric    typedef __assoc_sub_state base;
9850b57cec5SDimitry Andric
9860b57cec5SDimitry Andric    _Fp __func_;
9870b57cec5SDimitry Andric
98806c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
9890b57cec5SDimitry Andricpublic:
990*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
9910b57cec5SDimitry Andric    explicit __async_assoc_state(_Fp&& __f);
9920b57cec5SDimitry Andric
99306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
9940b57cec5SDimitry Andric};
9950b57cec5SDimitry Andric
9960b57cec5SDimitry Andrictemplate <class _Fp>
9970b57cec5SDimitry Andricinline
9980b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
999*5f757f3fSDimitry Andric    : __func_(std::forward<_Fp>(__f))
10000b57cec5SDimitry Andric{
10010b57cec5SDimitry Andric}
10020b57cec5SDimitry Andric
10030b57cec5SDimitry Andrictemplate <class _Fp>
10040b57cec5SDimitry Andricvoid
10050b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__execute()
10060b57cec5SDimitry Andric{
100706c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
10080b57cec5SDimitry Andric    try
10090b57cec5SDimitry Andric    {
101006c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10110b57cec5SDimitry Andric        __func_();
10120b57cec5SDimitry Andric        this->set_value();
101306c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
10140b57cec5SDimitry Andric    }
10150b57cec5SDimitry Andric    catch (...)
10160b57cec5SDimitry Andric    {
10170b57cec5SDimitry Andric        this->set_exception(current_exception());
10180b57cec5SDimitry Andric    }
101906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
10200b57cec5SDimitry Andric}
10210b57cec5SDimitry Andric
10220b57cec5SDimitry Andrictemplate <class _Fp>
10230b57cec5SDimitry Andricvoid
10240b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
10250b57cec5SDimitry Andric{
10260b57cec5SDimitry Andric    this->wait();
10270b57cec5SDimitry Andric    base::__on_zero_shared();
10280b57cec5SDimitry Andric}
10290b57cec5SDimitry Andric
10300b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
10310b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
10320b57cec5SDimitry Andric
10330b57cec5SDimitry Andric// future
10340b57cec5SDimitry Andric
10350b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
10360b57cec5SDimitry Andric
10370b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1038*5f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp>
10390b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp&& __f);
10400b57cec5SDimitry Andric
10410b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1042*5f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp>
10430b57cec5SDimitry Andric__make_async_assoc_state(_Fp&& __f);
10440b57cec5SDimitry Andric
10450b57cec5SDimitry Andrictemplate <class _Rp>
1046*5f757f3fSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future
10470b57cec5SDimitry Andric{
10480b57cec5SDimitry Andric    __assoc_state<_Rp>* __state_;
10490b57cec5SDimitry Andric
105006c3fb27SDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state);
10510b57cec5SDimitry Andric
10520b57cec5SDimitry Andric    template <class> friend class promise;
10530b57cec5SDimitry Andric    template <class> friend class shared_future;
10540b57cec5SDimitry Andric
10550b57cec5SDimitry Andric    template <class _R1, class _Fp>
10560b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
10570b57cec5SDimitry Andric    template <class _R1, class _Fp>
10580b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
10590b57cec5SDimitry Andric
10600b57cec5SDimitry Andricpublic:
1061*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
10620b57cec5SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
1063*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
10640b57cec5SDimitry Andric    future(future&& __rhs) _NOEXCEPT
10650b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
10660b57cec5SDimitry Andric    future(const future&) = delete;
10670b57cec5SDimitry Andric    future& operator=(const future&) = delete;
1068*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
10690b57cec5SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
10700b57cec5SDimitry Andric        {
1071*5f757f3fSDimitry Andric            future(std::move(__rhs)).swap(*this);
10720b57cec5SDimitry Andric            return *this;
10730b57cec5SDimitry Andric        }
1074e8d8bef9SDimitry Andric
107506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~future();
1076*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
10770b57cec5SDimitry Andric    shared_future<_Rp> share() _NOEXCEPT;
10780b57cec5SDimitry Andric
10790b57cec5SDimitry Andric    // retrieving the value
108006c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI _Rp get();
10810b57cec5SDimitry Andric
1082*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1083*5f757f3fSDimitry Andric    void swap(future& __rhs) _NOEXCEPT {std::swap(__state_, __rhs.__state_);}
10840b57cec5SDimitry Andric
10850b57cec5SDimitry Andric    // functions to check state
1086*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
10870b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
10880b57cec5SDimitry Andric
1089*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
10900b57cec5SDimitry Andric    void wait() const {__state_->wait();}
10910b57cec5SDimitry Andric    template <class _Rep, class _Period>
1092*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
10930b57cec5SDimitry Andric        future_status
10940b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
10950b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
10960b57cec5SDimitry Andric    template <class _Clock, class _Duration>
1097*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
10980b57cec5SDimitry Andric        future_status
10990b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
11000b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
11010b57cec5SDimitry Andric};
11020b57cec5SDimitry Andric
11030b57cec5SDimitry Andrictemplate <class _Rp>
11040b57cec5SDimitry Andricfuture<_Rp>::future(__assoc_state<_Rp>* __state)
11050b57cec5SDimitry Andric    : __state_(__state)
11060b57cec5SDimitry Andric{
11070b57cec5SDimitry Andric    __state_->__attach_future();
11080b57cec5SDimitry Andric}
11090b57cec5SDimitry Andric
11100b57cec5SDimitry Andricstruct __release_shared_count
11110b57cec5SDimitry Andric{
111206c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) {__p->__release_shared();}
11130b57cec5SDimitry Andric};
11140b57cec5SDimitry Andric
11150b57cec5SDimitry Andrictemplate <class _Rp>
11160b57cec5SDimitry Andricfuture<_Rp>::~future()
11170b57cec5SDimitry Andric{
11180b57cec5SDimitry Andric    if (__state_)
11190b57cec5SDimitry Andric        __state_->__release_shared();
11200b57cec5SDimitry Andric}
11210b57cec5SDimitry Andric
11220b57cec5SDimitry Andrictemplate <class _Rp>
11230b57cec5SDimitry Andric_Rp
11240b57cec5SDimitry Andricfuture<_Rp>::get()
11250b57cec5SDimitry Andric{
112606c3fb27SDimitry Andric    unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
11270b57cec5SDimitry Andric    __assoc_state<_Rp>* __s = __state_;
11280b57cec5SDimitry Andric    __state_ = nullptr;
11290b57cec5SDimitry Andric    return __s->move();
11300b57cec5SDimitry Andric}
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andrictemplate <class _Rp>
1133*5f757f3fSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future<_Rp&>
11340b57cec5SDimitry Andric{
11350b57cec5SDimitry Andric    __assoc_state<_Rp&>* __state_;
11360b57cec5SDimitry Andric
113706c3fb27SDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state);
11380b57cec5SDimitry Andric
11390b57cec5SDimitry Andric    template <class> friend class promise;
11400b57cec5SDimitry Andric    template <class> friend class shared_future;
11410b57cec5SDimitry Andric
11420b57cec5SDimitry Andric    template <class _R1, class _Fp>
11430b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
11440b57cec5SDimitry Andric    template <class _R1, class _Fp>
11450b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
11460b57cec5SDimitry Andric
11470b57cec5SDimitry Andricpublic:
1148*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
11490b57cec5SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
1150*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
11510b57cec5SDimitry Andric    future(future&& __rhs) _NOEXCEPT
11520b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
11530b57cec5SDimitry Andric    future(const future&) = delete;
11540b57cec5SDimitry Andric    future& operator=(const future&) = delete;
1155*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
11560b57cec5SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
11570b57cec5SDimitry Andric        {
1158*5f757f3fSDimitry Andric            future(std::move(__rhs)).swap(*this);
11590b57cec5SDimitry Andric            return *this;
11600b57cec5SDimitry Andric        }
1161e8d8bef9SDimitry Andric
116206c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~future();
1163*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
11640b57cec5SDimitry Andric    shared_future<_Rp&> share() _NOEXCEPT;
11650b57cec5SDimitry Andric
11660b57cec5SDimitry Andric    // retrieving the value
116706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI _Rp& get();
11680b57cec5SDimitry Andric
1169*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1170*5f757f3fSDimitry Andric    void swap(future& __rhs) _NOEXCEPT {std::swap(__state_, __rhs.__state_);}
11710b57cec5SDimitry Andric
11720b57cec5SDimitry Andric    // functions to check state
1173*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
11740b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
11750b57cec5SDimitry Andric
1176*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
11770b57cec5SDimitry Andric    void wait() const {__state_->wait();}
11780b57cec5SDimitry Andric    template <class _Rep, class _Period>
1179*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
11800b57cec5SDimitry Andric        future_status
11810b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
11820b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
11830b57cec5SDimitry Andric    template <class _Clock, class _Duration>
1184*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
11850b57cec5SDimitry Andric        future_status
11860b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
11870b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
11880b57cec5SDimitry Andric};
11890b57cec5SDimitry Andric
11900b57cec5SDimitry Andrictemplate <class _Rp>
11910b57cec5SDimitry Andricfuture<_Rp&>::future(__assoc_state<_Rp&>* __state)
11920b57cec5SDimitry Andric    : __state_(__state)
11930b57cec5SDimitry Andric{
11940b57cec5SDimitry Andric    __state_->__attach_future();
11950b57cec5SDimitry Andric}
11960b57cec5SDimitry Andric
11970b57cec5SDimitry Andrictemplate <class _Rp>
11980b57cec5SDimitry Andricfuture<_Rp&>::~future()
11990b57cec5SDimitry Andric{
12000b57cec5SDimitry Andric    if (__state_)
12010b57cec5SDimitry Andric        __state_->__release_shared();
12020b57cec5SDimitry Andric}
12030b57cec5SDimitry Andric
12040b57cec5SDimitry Andrictemplate <class _Rp>
12050b57cec5SDimitry Andric_Rp&
12060b57cec5SDimitry Andricfuture<_Rp&>::get()
12070b57cec5SDimitry Andric{
120806c3fb27SDimitry Andric    unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
12090b57cec5SDimitry Andric    __assoc_state<_Rp&>* __s = __state_;
12100b57cec5SDimitry Andric    __state_ = nullptr;
12110b57cec5SDimitry Andric    return __s->copy();
12120b57cec5SDimitry Andric}
12130b57cec5SDimitry Andric
12140b57cec5SDimitry Andrictemplate <>
1215*5f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future<void>
12160b57cec5SDimitry Andric{
12170b57cec5SDimitry Andric    __assoc_sub_state* __state_;
12180b57cec5SDimitry Andric
12190b57cec5SDimitry Andric    explicit future(__assoc_sub_state* __state);
12200b57cec5SDimitry Andric
12210b57cec5SDimitry Andric    template <class> friend class promise;
12220b57cec5SDimitry Andric    template <class> friend class shared_future;
12230b57cec5SDimitry Andric
12240b57cec5SDimitry Andric    template <class _R1, class _Fp>
12250b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
12260b57cec5SDimitry Andric    template <class _R1, class _Fp>
12270b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
12280b57cec5SDimitry Andric
12290b57cec5SDimitry Andricpublic:
1230*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12310b57cec5SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
1232*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12330b57cec5SDimitry Andric    future(future&& __rhs) _NOEXCEPT
12340b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
12350b57cec5SDimitry Andric    future(const future&) = delete;
12360b57cec5SDimitry Andric    future& operator=(const future&) = delete;
1237*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12380b57cec5SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
12390b57cec5SDimitry Andric        {
1240*5f757f3fSDimitry Andric            future(std::move(__rhs)).swap(*this);
12410b57cec5SDimitry Andric            return *this;
12420b57cec5SDimitry Andric        }
1243e8d8bef9SDimitry Andric
12440b57cec5SDimitry Andric    ~future();
1245*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12460b57cec5SDimitry Andric    shared_future<void> share() _NOEXCEPT;
12470b57cec5SDimitry Andric
12480b57cec5SDimitry Andric    // retrieving the value
12490b57cec5SDimitry Andric    void get();
12500b57cec5SDimitry Andric
1251*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1252*5f757f3fSDimitry Andric    void swap(future& __rhs) _NOEXCEPT {std::swap(__state_, __rhs.__state_);}
12530b57cec5SDimitry Andric
12540b57cec5SDimitry Andric    // functions to check state
1255*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12560b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
12570b57cec5SDimitry Andric
1258*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12590b57cec5SDimitry Andric    void wait() const {__state_->wait();}
12600b57cec5SDimitry Andric    template <class _Rep, class _Period>
1261*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
12620b57cec5SDimitry Andric        future_status
12630b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
12640b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
12650b57cec5SDimitry Andric    template <class _Clock, class _Duration>
1266*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
12670b57cec5SDimitry Andric        future_status
12680b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
12690b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
12700b57cec5SDimitry Andric};
12710b57cec5SDimitry Andric
12720b57cec5SDimitry Andrictemplate <class _Rp>
1273*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
12740b57cec5SDimitry Andricvoid
12750b57cec5SDimitry Andricswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
12760b57cec5SDimitry Andric{
12770b57cec5SDimitry Andric    __x.swap(__y);
12780b57cec5SDimitry Andric}
12790b57cec5SDimitry Andric
12800b57cec5SDimitry Andric// promise<R>
12810b57cec5SDimitry Andric
12820b57cec5SDimitry Andrictemplate <class _Callable> class packaged_task;
12830b57cec5SDimitry Andric
12840b57cec5SDimitry Andrictemplate <class _Rp>
1285*5f757f3fSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise
12860b57cec5SDimitry Andric{
12870b57cec5SDimitry Andric    __assoc_state<_Rp>* __state_;
12880b57cec5SDimitry Andric
1289*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12900b57cec5SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
12910b57cec5SDimitry Andric
12920b57cec5SDimitry Andric    template <class> friend class packaged_task;
12930b57cec5SDimitry Andricpublic:
129406c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI promise();
12950b57cec5SDimitry Andric    template <class _Alloc>
129606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a);
1297*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
12980b57cec5SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
12990b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
13000b57cec5SDimitry Andric    promise(const promise& __rhs) = delete;
130106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~promise();
13020b57cec5SDimitry Andric
13030b57cec5SDimitry Andric    // assignment
1304*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
13050b57cec5SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
13060b57cec5SDimitry Andric        {
1307*5f757f3fSDimitry Andric            promise(std::move(__rhs)).swap(*this);
13080b57cec5SDimitry Andric            return *this;
13090b57cec5SDimitry Andric        }
13100b57cec5SDimitry Andric    promise& operator=(const promise& __rhs) = delete;
1311e8d8bef9SDimitry Andric
1312*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1313*5f757f3fSDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {std::swap(__state_, __rhs.__state_);}
13140b57cec5SDimitry Andric
13150b57cec5SDimitry Andric    // retrieving the result
131606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future();
13170b57cec5SDimitry Andric
13180b57cec5SDimitry Andric    // setting the result
131906c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r);
132006c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r);
132106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
13220b57cec5SDimitry Andric
13230b57cec5SDimitry Andric    // setting the result with deferred notification
132406c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r);
132506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r);
132606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
13270b57cec5SDimitry Andric};
13280b57cec5SDimitry Andric
13290b57cec5SDimitry Andrictemplate <class _Rp>
13300b57cec5SDimitry Andricpromise<_Rp>::promise()
13310b57cec5SDimitry Andric    : __state_(new __assoc_state<_Rp>)
13320b57cec5SDimitry Andric{
13330b57cec5SDimitry Andric}
13340b57cec5SDimitry Andric
13350b57cec5SDimitry Andrictemplate <class _Rp>
13360b57cec5SDimitry Andrictemplate <class _Alloc>
13370b57cec5SDimitry Andricpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
13380b57cec5SDimitry Andric{
13390b57cec5SDimitry Andric    typedef __assoc_state_alloc<_Rp, _Alloc> _State;
13400b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
13410b57cec5SDimitry Andric    typedef __allocator_destructor<_A2> _D2;
13420b57cec5SDimitry Andric    _A2 __a(__a0);
13430b57cec5SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1344*5f757f3fSDimitry Andric    ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
1345*5f757f3fSDimitry Andric    __state_ = std::addressof(*__hold.release());
13460b57cec5SDimitry Andric}
13470b57cec5SDimitry Andric
13480b57cec5SDimitry Andrictemplate <class _Rp>
13490b57cec5SDimitry Andricpromise<_Rp>::~promise()
13500b57cec5SDimitry Andric{
13510b57cec5SDimitry Andric    if (__state_)
13520b57cec5SDimitry Andric    {
13530b57cec5SDimitry Andric        if (!__state_->__has_value() && __state_->use_count() > 1)
1354*5f757f3fSDimitry Andric            __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise))));
13550b57cec5SDimitry Andric        __state_->__release_shared();
13560b57cec5SDimitry Andric    }
13570b57cec5SDimitry Andric}
13580b57cec5SDimitry Andric
13590b57cec5SDimitry Andrictemplate <class _Rp>
13600b57cec5SDimitry Andricfuture<_Rp>
13610b57cec5SDimitry Andricpromise<_Rp>::get_future()
13620b57cec5SDimitry Andric{
13630b57cec5SDimitry Andric    if (__state_ == nullptr)
13640b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
13650b57cec5SDimitry Andric    return future<_Rp>(__state_);
13660b57cec5SDimitry Andric}
13670b57cec5SDimitry Andric
13680b57cec5SDimitry Andrictemplate <class _Rp>
13690b57cec5SDimitry Andricvoid
13700b57cec5SDimitry Andricpromise<_Rp>::set_value(const _Rp& __r)
13710b57cec5SDimitry Andric{
13720b57cec5SDimitry Andric    if (__state_ == nullptr)
13730b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
13740b57cec5SDimitry Andric    __state_->set_value(__r);
13750b57cec5SDimitry Andric}
13760b57cec5SDimitry Andric
13770b57cec5SDimitry Andrictemplate <class _Rp>
13780b57cec5SDimitry Andricvoid
13790b57cec5SDimitry Andricpromise<_Rp>::set_value(_Rp&& __r)
13800b57cec5SDimitry Andric{
13810b57cec5SDimitry Andric    if (__state_ == nullptr)
13820b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1383*5f757f3fSDimitry Andric    __state_->set_value(std::move(__r));
13840b57cec5SDimitry Andric}
13850b57cec5SDimitry Andric
13860b57cec5SDimitry Andrictemplate <class _Rp>
13870b57cec5SDimitry Andricvoid
13880b57cec5SDimitry Andricpromise<_Rp>::set_exception(exception_ptr __p)
13890b57cec5SDimitry Andric{
1390*5f757f3fSDimitry Andric    _LIBCPP_ASSERT_NON_NULL( __p != nullptr, "promise::set_exception: received nullptr" );
13910b57cec5SDimitry Andric    if (__state_ == nullptr)
13920b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
13930b57cec5SDimitry Andric    __state_->set_exception(__p);
13940b57cec5SDimitry Andric}
13950b57cec5SDimitry Andric
13960b57cec5SDimitry Andrictemplate <class _Rp>
13970b57cec5SDimitry Andricvoid
13980b57cec5SDimitry Andricpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
13990b57cec5SDimitry Andric{
14000b57cec5SDimitry Andric    if (__state_ == nullptr)
14010b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
14020b57cec5SDimitry Andric    __state_->set_value_at_thread_exit(__r);
14030b57cec5SDimitry Andric}
14040b57cec5SDimitry Andric
14050b57cec5SDimitry Andrictemplate <class _Rp>
14060b57cec5SDimitry Andricvoid
14070b57cec5SDimitry Andricpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
14080b57cec5SDimitry Andric{
14090b57cec5SDimitry Andric    if (__state_ == nullptr)
14100b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1411*5f757f3fSDimitry Andric    __state_->set_value_at_thread_exit(std::move(__r));
14120b57cec5SDimitry Andric}
14130b57cec5SDimitry Andric
14140b57cec5SDimitry Andrictemplate <class _Rp>
14150b57cec5SDimitry Andricvoid
14160b57cec5SDimitry Andricpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
14170b57cec5SDimitry Andric{
1418*5f757f3fSDimitry Andric    _LIBCPP_ASSERT_NON_NULL( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
14190b57cec5SDimitry Andric    if (__state_ == nullptr)
14200b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
14210b57cec5SDimitry Andric    __state_->set_exception_at_thread_exit(__p);
14220b57cec5SDimitry Andric}
14230b57cec5SDimitry Andric
14240b57cec5SDimitry Andric// promise<R&>
14250b57cec5SDimitry Andric
14260b57cec5SDimitry Andrictemplate <class _Rp>
1427*5f757f3fSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise<_Rp&>
14280b57cec5SDimitry Andric{
14290b57cec5SDimitry Andric    __assoc_state<_Rp&>* __state_;
14300b57cec5SDimitry Andric
1431*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
14320b57cec5SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
14330b57cec5SDimitry Andric
14340b57cec5SDimitry Andric    template <class> friend class packaged_task;
14350b57cec5SDimitry Andric
14360b57cec5SDimitry Andricpublic:
143706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI promise();
14380b57cec5SDimitry Andric    template <class _Allocator>
143906c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a);
1440*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
14410b57cec5SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
14420b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
14430b57cec5SDimitry Andric    promise(const promise& __rhs) = delete;
144406c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~promise();
14450b57cec5SDimitry Andric
14460b57cec5SDimitry Andric    // assignment
1447*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
14480b57cec5SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
14490b57cec5SDimitry Andric        {
1450*5f757f3fSDimitry Andric            promise(std::move(__rhs)).swap(*this);
14510b57cec5SDimitry Andric            return *this;
14520b57cec5SDimitry Andric        }
14530b57cec5SDimitry Andric    promise& operator=(const promise& __rhs) = delete;
1454e8d8bef9SDimitry Andric
1455*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1456*5f757f3fSDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {std::swap(__state_, __rhs.__state_);}
14570b57cec5SDimitry Andric
14580b57cec5SDimitry Andric    // retrieving the result
145906c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future();
14600b57cec5SDimitry Andric
14610b57cec5SDimitry Andric    // setting the result
146206c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r);
146306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
14640b57cec5SDimitry Andric
14650b57cec5SDimitry Andric    // setting the result with deferred notification
146606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&);
146706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
14680b57cec5SDimitry Andric};
14690b57cec5SDimitry Andric
14700b57cec5SDimitry Andrictemplate <class _Rp>
14710b57cec5SDimitry Andricpromise<_Rp&>::promise()
14720b57cec5SDimitry Andric    : __state_(new __assoc_state<_Rp&>)
14730b57cec5SDimitry Andric{
14740b57cec5SDimitry Andric}
14750b57cec5SDimitry Andric
14760b57cec5SDimitry Andrictemplate <class _Rp>
14770b57cec5SDimitry Andrictemplate <class _Alloc>
14780b57cec5SDimitry Andricpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
14790b57cec5SDimitry Andric{
14800b57cec5SDimitry Andric    typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
14810b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
14820b57cec5SDimitry Andric    typedef __allocator_destructor<_A2> _D2;
14830b57cec5SDimitry Andric    _A2 __a(__a0);
14840b57cec5SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1485*5f757f3fSDimitry Andric    ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
1486*5f757f3fSDimitry Andric    __state_ = std::addressof(*__hold.release());
14870b57cec5SDimitry Andric}
14880b57cec5SDimitry Andric
14890b57cec5SDimitry Andrictemplate <class _Rp>
14900b57cec5SDimitry Andricpromise<_Rp&>::~promise()
14910b57cec5SDimitry Andric{
14920b57cec5SDimitry Andric    if (__state_)
14930b57cec5SDimitry Andric    {
14940b57cec5SDimitry Andric        if (!__state_->__has_value() && __state_->use_count() > 1)
1495*5f757f3fSDimitry Andric            __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise))));
14960b57cec5SDimitry Andric        __state_->__release_shared();
14970b57cec5SDimitry Andric    }
14980b57cec5SDimitry Andric}
14990b57cec5SDimitry Andric
15000b57cec5SDimitry Andrictemplate <class _Rp>
15010b57cec5SDimitry Andricfuture<_Rp&>
15020b57cec5SDimitry Andricpromise<_Rp&>::get_future()
15030b57cec5SDimitry Andric{
15040b57cec5SDimitry Andric    if (__state_ == nullptr)
15050b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
15060b57cec5SDimitry Andric    return future<_Rp&>(__state_);
15070b57cec5SDimitry Andric}
15080b57cec5SDimitry Andric
15090b57cec5SDimitry Andrictemplate <class _Rp>
15100b57cec5SDimitry Andricvoid
15110b57cec5SDimitry Andricpromise<_Rp&>::set_value(_Rp& __r)
15120b57cec5SDimitry Andric{
15130b57cec5SDimitry Andric    if (__state_ == nullptr)
15140b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
15150b57cec5SDimitry Andric    __state_->set_value(__r);
15160b57cec5SDimitry Andric}
15170b57cec5SDimitry Andric
15180b57cec5SDimitry Andrictemplate <class _Rp>
15190b57cec5SDimitry Andricvoid
15200b57cec5SDimitry Andricpromise<_Rp&>::set_exception(exception_ptr __p)
15210b57cec5SDimitry Andric{
1522*5f757f3fSDimitry Andric    _LIBCPP_ASSERT_NON_NULL( __p != nullptr, "promise::set_exception: received nullptr" );
15230b57cec5SDimitry Andric    if (__state_ == nullptr)
15240b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
15250b57cec5SDimitry Andric    __state_->set_exception(__p);
15260b57cec5SDimitry Andric}
15270b57cec5SDimitry Andric
15280b57cec5SDimitry Andrictemplate <class _Rp>
15290b57cec5SDimitry Andricvoid
15300b57cec5SDimitry Andricpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
15310b57cec5SDimitry Andric{
15320b57cec5SDimitry Andric    if (__state_ == nullptr)
15330b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
15340b57cec5SDimitry Andric    __state_->set_value_at_thread_exit(__r);
15350b57cec5SDimitry Andric}
15360b57cec5SDimitry Andric
15370b57cec5SDimitry Andrictemplate <class _Rp>
15380b57cec5SDimitry Andricvoid
15390b57cec5SDimitry Andricpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
15400b57cec5SDimitry Andric{
1541*5f757f3fSDimitry Andric    _LIBCPP_ASSERT_NON_NULL( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
15420b57cec5SDimitry Andric    if (__state_ == nullptr)
15430b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
15440b57cec5SDimitry Andric    __state_->set_exception_at_thread_exit(__p);
15450b57cec5SDimitry Andric}
15460b57cec5SDimitry Andric
15470b57cec5SDimitry Andric// promise<void>
15480b57cec5SDimitry Andric
15490b57cec5SDimitry Andrictemplate <>
1550*5f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI promise<void>
15510b57cec5SDimitry Andric{
15520b57cec5SDimitry Andric    __assoc_sub_state* __state_;
15530b57cec5SDimitry Andric
1554*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
15550b57cec5SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
15560b57cec5SDimitry Andric
15570b57cec5SDimitry Andric    template <class> friend class packaged_task;
15580b57cec5SDimitry Andric
15590b57cec5SDimitry Andricpublic:
15600b57cec5SDimitry Andric    promise();
15610b57cec5SDimitry Andric    template <class _Allocator>
15620b57cec5SDimitry Andric        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
15630b57cec5SDimitry Andric        promise(allocator_arg_t, const _Allocator& __a);
1564*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
15650b57cec5SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
15660b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
15670b57cec5SDimitry Andric    promise(const promise& __rhs) = delete;
15680b57cec5SDimitry Andric    ~promise();
15690b57cec5SDimitry Andric
15700b57cec5SDimitry Andric    // assignment
1571*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
15720b57cec5SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
15730b57cec5SDimitry Andric        {
1574*5f757f3fSDimitry Andric            promise(std::move(__rhs)).swap(*this);
15750b57cec5SDimitry Andric            return *this;
15760b57cec5SDimitry Andric        }
15770b57cec5SDimitry Andric    promise& operator=(const promise& __rhs) = delete;
1578e8d8bef9SDimitry Andric
1579*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1580*5f757f3fSDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {std::swap(__state_, __rhs.__state_);}
15810b57cec5SDimitry Andric
15820b57cec5SDimitry Andric    // retrieving the result
15830b57cec5SDimitry Andric    future<void> get_future();
15840b57cec5SDimitry Andric
15850b57cec5SDimitry Andric    // setting the result
15860b57cec5SDimitry Andric    void set_value();
15870b57cec5SDimitry Andric    void set_exception(exception_ptr __p);
15880b57cec5SDimitry Andric
15890b57cec5SDimitry Andric    // setting the result with deferred notification
15900b57cec5SDimitry Andric    void set_value_at_thread_exit();
15910b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr __p);
15920b57cec5SDimitry Andric};
15930b57cec5SDimitry Andric
15940b57cec5SDimitry Andrictemplate <class _Alloc>
15950b57cec5SDimitry Andricpromise<void>::promise(allocator_arg_t, const _Alloc& __a0)
15960b57cec5SDimitry Andric{
15970b57cec5SDimitry Andric    typedef __assoc_sub_state_alloc<_Alloc> _State;
15980b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
15990b57cec5SDimitry Andric    typedef __allocator_destructor<_A2> _D2;
16000b57cec5SDimitry Andric    _A2 __a(__a0);
16010b57cec5SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1602*5f757f3fSDimitry Andric    ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
1603*5f757f3fSDimitry Andric    __state_ = std::addressof(*__hold.release());
16040b57cec5SDimitry Andric}
16050b57cec5SDimitry Andric
16060b57cec5SDimitry Andrictemplate <class _Rp>
1607*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
16080b57cec5SDimitry Andricvoid
16090b57cec5SDimitry Andricswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
16100b57cec5SDimitry Andric{
16110b57cec5SDimitry Andric    __x.swap(__y);
16120b57cec5SDimitry Andric}
16130b57cec5SDimitry Andric
16140b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
16150b57cec5SDimitry Andric    struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
16160b57cec5SDimitry Andric        : public true_type {};
16170b57cec5SDimitry Andric
16180b57cec5SDimitry Andric// packaged_task
16190b57cec5SDimitry Andric
16200b57cec5SDimitry Andrictemplate<class _Fp> class __packaged_task_base;
16210b57cec5SDimitry Andric
16220b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1623*5f757f3fSDimitry Andricclass __packaged_task_base<_Rp(_ArgTypes...)>
16240b57cec5SDimitry Andric{
16250b57cec5SDimitry Andric    __packaged_task_base(const __packaged_task_base&);
16260b57cec5SDimitry Andric    __packaged_task_base& operator=(const __packaged_task_base&);
16270b57cec5SDimitry Andricpublic:
1628*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
16290b57cec5SDimitry Andric    __packaged_task_base() {}
1630bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL
16310b57cec5SDimitry Andric    virtual ~__packaged_task_base() {}
16320b57cec5SDimitry Andric    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
16330b57cec5SDimitry Andric    virtual void destroy() = 0;
16340b57cec5SDimitry Andric    virtual void destroy_deallocate() = 0;
16350b57cec5SDimitry Andric    virtual _Rp operator()(_ArgTypes&& ...) = 0;
16360b57cec5SDimitry Andric};
16370b57cec5SDimitry Andric
16380b57cec5SDimitry Andrictemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func;
16390b57cec5SDimitry Andric
16400b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1641*5f757f3fSDimitry Andricclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public  __packaged_task_base<_Rp(_ArgTypes...)>
16420b57cec5SDimitry Andric{
16430b57cec5SDimitry Andric    __compressed_pair<_Fp, _Alloc> __f_;
16440b57cec5SDimitry Andricpublic:
1645*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1646480093f4SDimitry Andric    explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
1647*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
1648*5f757f3fSDimitry Andric    explicit __packaged_task_func(_Fp&& __f) : __f_(std::move(__f), __default_init_tag()) {}
1649*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
16500b57cec5SDimitry Andric    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
16510b57cec5SDimitry Andric        : __f_(__f, __a) {}
1652*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
16530b57cec5SDimitry Andric    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
1654*5f757f3fSDimitry Andric        : __f_(std::move(__f), __a) {}
165506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
165606c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy();
165706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate();
165806c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&& ... __args);
16590b57cec5SDimitry Andric};
16600b57cec5SDimitry Andric
16610b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
16620b57cec5SDimitry Andricvoid
16630b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
16640b57cec5SDimitry Andric                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
16650b57cec5SDimitry Andric{
1666*5f757f3fSDimitry Andric    ::new ((void*)__p) __packaged_task_func(std::move(__f_.first()), std::move(__f_.second()));
16670b57cec5SDimitry Andric}
16680b57cec5SDimitry Andric
16690b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
16700b57cec5SDimitry Andricvoid
16710b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
16720b57cec5SDimitry Andric{
16730b57cec5SDimitry Andric    __f_.~__compressed_pair<_Fp, _Alloc>();
16740b57cec5SDimitry Andric}
16750b57cec5SDimitry Andric
16760b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
16770b57cec5SDimitry Andricvoid
16780b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
16790b57cec5SDimitry Andric{
16800b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
16810b57cec5SDimitry Andric    typedef allocator_traits<_Ap> _ATraits;
16820b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
16830b57cec5SDimitry Andric    _Ap __a(__f_.second());
16840b57cec5SDimitry Andric    __f_.~__compressed_pair<_Fp, _Alloc>();
16850b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
16860b57cec5SDimitry Andric}
16870b57cec5SDimitry Andric
16880b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
16890b57cec5SDimitry Andric_Rp
16900b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
16910b57cec5SDimitry Andric{
1692*5f757f3fSDimitry Andric    return std::__invoke(__f_.first(), std::forward<_ArgTypes>(__arg)...);
16930b57cec5SDimitry Andric}
16940b57cec5SDimitry Andric
16950b57cec5SDimitry Andrictemplate <class _Callable> class __packaged_task_function;
16960b57cec5SDimitry Andric
16970b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1698*5f757f3fSDimitry Andricclass __packaged_task_function<_Rp(_ArgTypes...)>
16990b57cec5SDimitry Andric{
17000b57cec5SDimitry Andric    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1701e8d8bef9SDimitry Andric
1702*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI
1703e8d8bef9SDimitry Andric    __base* __get_buf() { return (__base*)&__buf_; }
1704e8d8bef9SDimitry Andric
1705bdd1243dSDimitry Andric    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
17060b57cec5SDimitry Andric    typename aligned_storage<3*sizeof(void*)>::type __buf_;
1707bdd1243dSDimitry Andric    _LIBCPP_SUPPRESS_DEPRECATED_POP
17080b57cec5SDimitry Andric    __base* __f_;
17090b57cec5SDimitry Andric
17100b57cec5SDimitry Andricpublic:
17110b57cec5SDimitry Andric    typedef _Rp result_type;
17120b57cec5SDimitry Andric
17130b57cec5SDimitry Andric    // construct/copy/destroy:
1714*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
17150b57cec5SDimitry Andric    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
17160b57cec5SDimitry Andric    template<class _Fp>
171706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f);
17180b57cec5SDimitry Andric    template<class _Fp, class _Alloc>
171906c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
17200b57cec5SDimitry Andric
172106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
172206c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
17230b57cec5SDimitry Andric
17240b57cec5SDimitry Andric    __packaged_task_function(const __packaged_task_function&) =  delete;
17250b57cec5SDimitry Andric    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
17260b57cec5SDimitry Andric
172706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function();
17280b57cec5SDimitry Andric
172906c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT;
17300b57cec5SDimitry Andric
1731*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
173206c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
17330b57cec5SDimitry Andric};
17340b57cec5SDimitry Andric
17350b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
17360b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
17370b57cec5SDimitry Andric{
17380b57cec5SDimitry Andric    if (__f.__f_ == nullptr)
17390b57cec5SDimitry Andric        __f_ = nullptr;
1740e8d8bef9SDimitry Andric    else if (__f.__f_ == __f.__get_buf())
17410b57cec5SDimitry Andric    {
1742e8d8bef9SDimitry Andric        __f.__f_->__move_to(__get_buf());
17430b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
17440b57cec5SDimitry Andric    }
17450b57cec5SDimitry Andric    else
17460b57cec5SDimitry Andric    {
17470b57cec5SDimitry Andric        __f_ = __f.__f_;
17480b57cec5SDimitry Andric        __f.__f_ = nullptr;
17490b57cec5SDimitry Andric    }
17500b57cec5SDimitry Andric}
17510b57cec5SDimitry Andric
17520b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
17530b57cec5SDimitry Andrictemplate <class _Fp>
17540b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
17550b57cec5SDimitry Andric    : __f_(nullptr)
17560b57cec5SDimitry Andric{
175706c3fb27SDimitry Andric    typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
17580b57cec5SDimitry Andric    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
17590b57cec5SDimitry Andric    if (sizeof(_FF) <= sizeof(__buf_))
17600b57cec5SDimitry Andric    {
1761*5f757f3fSDimitry Andric        ::new ((void*)&__buf_) _FF(std::forward<_Fp>(__f));
17620b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
17630b57cec5SDimitry Andric    }
17640b57cec5SDimitry Andric    else
17650b57cec5SDimitry Andric    {
17660b57cec5SDimitry Andric        typedef allocator<_FF> _Ap;
17670b57cec5SDimitry Andric        _Ap __a;
17680b57cec5SDimitry Andric        typedef __allocator_destructor<_Ap> _Dp;
17690b57cec5SDimitry Andric        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1770*5f757f3fSDimitry Andric        ::new ((void*)__hold.get()) _FF(std::forward<_Fp>(__f), allocator<_FR>(__a));
17710b57cec5SDimitry Andric        __f_ = __hold.release();
17720b57cec5SDimitry Andric    }
17730b57cec5SDimitry Andric}
17740b57cec5SDimitry Andric
17750b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
17760b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc>
17770b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
17780b57cec5SDimitry Andric                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
17790b57cec5SDimitry Andric    : __f_(nullptr)
17800b57cec5SDimitry Andric{
178106c3fb27SDimitry Andric    typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
17820b57cec5SDimitry Andric    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
17830b57cec5SDimitry Andric    if (sizeof(_FF) <= sizeof(__buf_))
17840b57cec5SDimitry Andric    {
17850b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
1786*5f757f3fSDimitry Andric        ::new ((void*)__f_) _FF(std::forward<_Fp>(__f));
17870b57cec5SDimitry Andric    }
17880b57cec5SDimitry Andric    else
17890b57cec5SDimitry Andric    {
17900b57cec5SDimitry Andric        typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
17910b57cec5SDimitry Andric        _Ap __a(__a0);
17920b57cec5SDimitry Andric        typedef __allocator_destructor<_Ap> _Dp;
17930b57cec5SDimitry Andric        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1794*5f757f3fSDimitry Andric        ::new ((void*)std::addressof(*__hold.get()))
1795*5f757f3fSDimitry Andric            _FF(std::forward<_Fp>(__f), _Alloc(__a));
1796*5f757f3fSDimitry Andric        __f_ = std::addressof(*__hold.release());
17970b57cec5SDimitry Andric    }
17980b57cec5SDimitry Andric}
17990b57cec5SDimitry Andric
18000b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
18010b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>&
18020b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
18030b57cec5SDimitry Andric{
1804e8d8bef9SDimitry Andric    if (__f_ == __get_buf())
18050b57cec5SDimitry Andric        __f_->destroy();
18060b57cec5SDimitry Andric    else if (__f_)
18070b57cec5SDimitry Andric        __f_->destroy_deallocate();
18080b57cec5SDimitry Andric    __f_ = nullptr;
18090b57cec5SDimitry Andric    if (__f.__f_ == nullptr)
18100b57cec5SDimitry Andric        __f_ = nullptr;
1811e8d8bef9SDimitry Andric    else if (__f.__f_ == __f.__get_buf())
18120b57cec5SDimitry Andric    {
1813e8d8bef9SDimitry Andric        __f.__f_->__move_to(__get_buf());
1814e8d8bef9SDimitry Andric        __f_ = __get_buf();
18150b57cec5SDimitry Andric    }
18160b57cec5SDimitry Andric    else
18170b57cec5SDimitry Andric    {
18180b57cec5SDimitry Andric        __f_ = __f.__f_;
18190b57cec5SDimitry Andric        __f.__f_ = nullptr;
18200b57cec5SDimitry Andric    }
18210b57cec5SDimitry Andric    return *this;
18220b57cec5SDimitry Andric}
18230b57cec5SDimitry Andric
18240b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
18250b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
18260b57cec5SDimitry Andric{
1827e8d8bef9SDimitry Andric    if (__f_ == __get_buf())
18280b57cec5SDimitry Andric        __f_->destroy();
18290b57cec5SDimitry Andric    else if (__f_)
18300b57cec5SDimitry Andric        __f_->destroy_deallocate();
18310b57cec5SDimitry Andric}
18320b57cec5SDimitry Andric
18330b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1834e8d8bef9SDimitry Andric_LIBCPP_NO_CFI
18350b57cec5SDimitry Andricvoid
18360b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
18370b57cec5SDimitry Andric{
18380b57cec5SDimitry Andric    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
18390b57cec5SDimitry Andric    {
1840bdd1243dSDimitry Andric        _LIBCPP_SUPPRESS_DEPRECATED_PUSH
18410b57cec5SDimitry Andric        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1842bdd1243dSDimitry Andric        _LIBCPP_SUPPRESS_DEPRECATED_POP
18430b57cec5SDimitry Andric        __base* __t = (__base*)&__tempbuf;
18440b57cec5SDimitry Andric        __f_->__move_to(__t);
18450b57cec5SDimitry Andric        __f_->destroy();
18460b57cec5SDimitry Andric        __f_ = nullptr;
18470b57cec5SDimitry Andric        __f.__f_->__move_to((__base*)&__buf_);
18480b57cec5SDimitry Andric        __f.__f_->destroy();
18490b57cec5SDimitry Andric        __f.__f_ = nullptr;
18500b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
18510b57cec5SDimitry Andric        __t->__move_to((__base*)&__f.__buf_);
18520b57cec5SDimitry Andric        __t->destroy();
18530b57cec5SDimitry Andric        __f.__f_ = (__base*)&__f.__buf_;
18540b57cec5SDimitry Andric    }
18550b57cec5SDimitry Andric    else if (__f_ == (__base*)&__buf_)
18560b57cec5SDimitry Andric    {
18570b57cec5SDimitry Andric        __f_->__move_to((__base*)&__f.__buf_);
18580b57cec5SDimitry Andric        __f_->destroy();
18590b57cec5SDimitry Andric        __f_ = __f.__f_;
18600b57cec5SDimitry Andric        __f.__f_ = (__base*)&__f.__buf_;
18610b57cec5SDimitry Andric    }
18620b57cec5SDimitry Andric    else if (__f.__f_ == (__base*)&__f.__buf_)
18630b57cec5SDimitry Andric    {
18640b57cec5SDimitry Andric        __f.__f_->__move_to((__base*)&__buf_);
18650b57cec5SDimitry Andric        __f.__f_->destroy();
18660b57cec5SDimitry Andric        __f.__f_ = __f_;
18670b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
18680b57cec5SDimitry Andric    }
18690b57cec5SDimitry Andric    else
1870*5f757f3fSDimitry Andric        std::swap(__f_, __f.__f_);
18710b57cec5SDimitry Andric}
18720b57cec5SDimitry Andric
18730b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
18740b57cec5SDimitry Andricinline
18750b57cec5SDimitry Andric_Rp
18760b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
18770b57cec5SDimitry Andric{
1878*5f757f3fSDimitry Andric    return (*__f_)(std::forward<_ArgTypes>(__arg)...);
18790b57cec5SDimitry Andric}
18800b57cec5SDimitry Andric
18810b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1882*5f757f3fSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<_Rp(_ArgTypes...)>
18830b57cec5SDimitry Andric{
18840b57cec5SDimitry Andricpublic:
18850b57cec5SDimitry Andric    typedef _Rp result_type; // extension
18860b57cec5SDimitry Andric
18870b57cec5SDimitry Andricprivate:
18880b57cec5SDimitry Andric    __packaged_task_function<result_type(_ArgTypes...)> __f_;
18890b57cec5SDimitry Andric    promise<result_type>                                __p_;
18900b57cec5SDimitry Andric
18910b57cec5SDimitry Andricpublic:
18920b57cec5SDimitry Andric    // construction and destruction
1893*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
18940b57cec5SDimitry Andric    packaged_task() _NOEXCEPT : __p_(nullptr) {}
18950b57cec5SDimitry Andric    template <class _Fp,
1896bdd1243dSDimitry Andric              class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
1897*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
1898*5f757f3fSDimitry Andric        explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
18990b57cec5SDimitry Andric    template <class _Fp, class _Allocator,
1900bdd1243dSDimitry Andric              class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
1901*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
19020b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1903*5f757f3fSDimitry Andric             : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)),
190406c3fb27SDimitry Andric               __p_(allocator_arg_t(), __a) {}
19050b57cec5SDimitry Andric    // ~packaged_task() = default;
19060b57cec5SDimitry Andric
19070b57cec5SDimitry Andric    // no copy
19080b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
19090b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
19100b57cec5SDimitry Andric
19110b57cec5SDimitry Andric    // move support
1912*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
19130b57cec5SDimitry Andric    packaged_task(packaged_task&& __other) _NOEXCEPT
1914*5f757f3fSDimitry Andric        : __f_(std::move(__other.__f_)), __p_(std::move(__other.__p_)) {}
1915*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
19160b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
19170b57cec5SDimitry Andric    {
1918*5f757f3fSDimitry Andric        __f_ = std::move(__other.__f_);
1919*5f757f3fSDimitry Andric        __p_ = std::move(__other.__p_);
19200b57cec5SDimitry Andric        return *this;
19210b57cec5SDimitry Andric    }
1922*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
19230b57cec5SDimitry Andric    void swap(packaged_task& __other) _NOEXCEPT
19240b57cec5SDimitry Andric    {
19250b57cec5SDimitry Andric        __f_.swap(__other.__f_);
19260b57cec5SDimitry Andric        __p_.swap(__other.__p_);
19270b57cec5SDimitry Andric    }
19280b57cec5SDimitry Andric
1929*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
19300b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
19310b57cec5SDimitry Andric
19320b57cec5SDimitry Andric    // result retrieval
1933*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
19340b57cec5SDimitry Andric    future<result_type> get_future() {return __p_.get_future();}
19350b57cec5SDimitry Andric
19360b57cec5SDimitry Andric    // execution
193706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
193806c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
19390b57cec5SDimitry Andric
194006c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void reset();
19410b57cec5SDimitry Andric};
19420b57cec5SDimitry Andric
19430b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
19440b57cec5SDimitry Andricvoid
19450b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
19460b57cec5SDimitry Andric{
19470b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
19480b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
19490b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
19500b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
195106c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
19520b57cec5SDimitry Andric    try
19530b57cec5SDimitry Andric    {
195406c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1955*5f757f3fSDimitry Andric        __p_.set_value(__f_(std::forward<_ArgTypes>(__args)...));
195606c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
19570b57cec5SDimitry Andric    }
19580b57cec5SDimitry Andric    catch (...)
19590b57cec5SDimitry Andric    {
19600b57cec5SDimitry Andric        __p_.set_exception(current_exception());
19610b57cec5SDimitry Andric    }
196206c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
19630b57cec5SDimitry Andric}
19640b57cec5SDimitry Andric
19650b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
19660b57cec5SDimitry Andricvoid
19670b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
19680b57cec5SDimitry Andric{
19690b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
19700b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
19710b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
19720b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
197306c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
19740b57cec5SDimitry Andric    try
19750b57cec5SDimitry Andric    {
197606c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1977*5f757f3fSDimitry Andric        __p_.set_value_at_thread_exit(__f_(std::forward<_ArgTypes>(__args)...));
197806c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
19790b57cec5SDimitry Andric    }
19800b57cec5SDimitry Andric    catch (...)
19810b57cec5SDimitry Andric    {
19820b57cec5SDimitry Andric        __p_.set_exception_at_thread_exit(current_exception());
19830b57cec5SDimitry Andric    }
198406c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
19850b57cec5SDimitry Andric}
19860b57cec5SDimitry Andric
19870b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
19880b57cec5SDimitry Andricvoid
19890b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::reset()
19900b57cec5SDimitry Andric{
19910b57cec5SDimitry Andric    if (!valid())
19920b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
19930b57cec5SDimitry Andric    __p_ = promise<result_type>();
19940b57cec5SDimitry Andric}
19950b57cec5SDimitry Andric
19960b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
1997*5f757f3fSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<void(_ArgTypes...)>
19980b57cec5SDimitry Andric{
19990b57cec5SDimitry Andricpublic:
20000b57cec5SDimitry Andric    typedef void result_type; // extension
20010b57cec5SDimitry Andric
20020b57cec5SDimitry Andricprivate:
20030b57cec5SDimitry Andric    __packaged_task_function<result_type(_ArgTypes...)> __f_;
20040b57cec5SDimitry Andric    promise<result_type>                                __p_;
20050b57cec5SDimitry Andric
20060b57cec5SDimitry Andricpublic:
20070b57cec5SDimitry Andric    // construction and destruction
2008*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
20090b57cec5SDimitry Andric    packaged_task() _NOEXCEPT : __p_(nullptr) {}
20100b57cec5SDimitry Andric    template <class _Fp,
2011bdd1243dSDimitry Andric              class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
2012*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
2013*5f757f3fSDimitry Andric        explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
20140b57cec5SDimitry Andric    template <class _Fp, class _Allocator,
2015bdd1243dSDimitry Andric              class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> >
2016*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
20170b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2018*5f757f3fSDimitry Andric             : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)),
201906c3fb27SDimitry Andric               __p_(allocator_arg_t(), __a) {}
20200b57cec5SDimitry Andric    // ~packaged_task() = default;
20210b57cec5SDimitry Andric
20220b57cec5SDimitry Andric    // no copy
20230b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
20240b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
20250b57cec5SDimitry Andric
20260b57cec5SDimitry Andric    // move support
2027*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
20280b57cec5SDimitry Andric    packaged_task(packaged_task&& __other) _NOEXCEPT
2029*5f757f3fSDimitry Andric        : __f_(std::move(__other.__f_)), __p_(std::move(__other.__p_)) {}
2030*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
20310b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
20320b57cec5SDimitry Andric    {
2033*5f757f3fSDimitry Andric        __f_ = std::move(__other.__f_);
2034*5f757f3fSDimitry Andric        __p_ = std::move(__other.__p_);
20350b57cec5SDimitry Andric        return *this;
20360b57cec5SDimitry Andric    }
2037*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
20380b57cec5SDimitry Andric    void swap(packaged_task& __other) _NOEXCEPT
20390b57cec5SDimitry Andric    {
20400b57cec5SDimitry Andric        __f_.swap(__other.__f_);
20410b57cec5SDimitry Andric        __p_.swap(__other.__p_);
20420b57cec5SDimitry Andric    }
20430b57cec5SDimitry Andric
2044*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
20450b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
20460b57cec5SDimitry Andric
20470b57cec5SDimitry Andric    // result retrieval
2048*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
20490b57cec5SDimitry Andric    future<result_type> get_future() {return __p_.get_future();}
20500b57cec5SDimitry Andric
20510b57cec5SDimitry Andric    // execution
205206c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
205306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
20540b57cec5SDimitry Andric
205506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI void reset();
20560b57cec5SDimitry Andric};
20570b57cec5SDimitry Andric
2058bdd1243dSDimitry Andric#if _LIBCPP_STD_VER >= 17
2059bdd1243dSDimitry Andric
2060bdd1243dSDimitry Andrictemplate <class _Rp, class... _Args>
2061bdd1243dSDimitry Andricpackaged_task(_Rp(*)(_Args...)) -> packaged_task<_Rp(_Args...)>;
2062bdd1243dSDimitry Andric
2063bdd1243dSDimitry Andrictemplate <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
2064bdd1243dSDimitry Andricpackaged_task(_Fp) -> packaged_task<_Stripped>;
2065bdd1243dSDimitry Andric
2066bdd1243dSDimitry Andric#endif
2067bdd1243dSDimitry Andric
20680b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
20690b57cec5SDimitry Andricvoid
20700b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
20710b57cec5SDimitry Andric{
20720b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
20730b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
20740b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
20750b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
207606c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
20770b57cec5SDimitry Andric    try
20780b57cec5SDimitry Andric    {
207906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2080*5f757f3fSDimitry Andric        __f_(std::forward<_ArgTypes>(__args)...);
20810b57cec5SDimitry Andric        __p_.set_value();
208206c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
20830b57cec5SDimitry Andric    }
20840b57cec5SDimitry Andric    catch (...)
20850b57cec5SDimitry Andric    {
20860b57cec5SDimitry Andric        __p_.set_exception(current_exception());
20870b57cec5SDimitry Andric    }
208806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
20890b57cec5SDimitry Andric}
20900b57cec5SDimitry Andric
20910b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
20920b57cec5SDimitry Andricvoid
20930b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
20940b57cec5SDimitry Andric{
20950b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
20960b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
20970b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
20980b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
209906c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
21000b57cec5SDimitry Andric    try
21010b57cec5SDimitry Andric    {
210206c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2103*5f757f3fSDimitry Andric        __f_(std::forward<_ArgTypes>(__args)...);
21040b57cec5SDimitry Andric        __p_.set_value_at_thread_exit();
210506c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
21060b57cec5SDimitry Andric    }
21070b57cec5SDimitry Andric    catch (...)
21080b57cec5SDimitry Andric    {
21090b57cec5SDimitry Andric        __p_.set_exception_at_thread_exit(current_exception());
21100b57cec5SDimitry Andric    }
211106c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
21120b57cec5SDimitry Andric}
21130b57cec5SDimitry Andric
21140b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
21150b57cec5SDimitry Andricvoid
21160b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::reset()
21170b57cec5SDimitry Andric{
21180b57cec5SDimitry Andric    if (!valid())
21190b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
21200b57cec5SDimitry Andric    __p_ = promise<result_type>();
21210b57cec5SDimitry Andric}
21220b57cec5SDimitry Andric
2123fe6060f1SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
2124*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
21250b57cec5SDimitry Andricvoid
2126fe6060f1SDimitry Andricswap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
21270b57cec5SDimitry Andric{
21280b57cec5SDimitry Andric    __x.swap(__y);
21290b57cec5SDimitry Andric}
21300b57cec5SDimitry Andric
21310b57cec5SDimitry Andrictemplate <class _Callable, class _Alloc>
21320b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
21330b57cec5SDimitry Andric    : public true_type {};
21340b57cec5SDimitry Andric
21350b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
2136*5f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp>
21370b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp&& __f)
21380b57cec5SDimitry Andric{
21390b57cec5SDimitry Andric    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2140*5f757f3fSDimitry Andric        __h(new __deferred_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
21410b57cec5SDimitry Andric    return future<_Rp>(__h.get());
21420b57cec5SDimitry Andric}
21430b57cec5SDimitry Andric
21440b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
2145*5f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp>
21460b57cec5SDimitry Andric__make_async_assoc_state(_Fp&& __f)
21470b57cec5SDimitry Andric{
21480b57cec5SDimitry Andric    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2149*5f757f3fSDimitry Andric        __h(new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
2150*5f757f3fSDimitry Andric    std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
21510b57cec5SDimitry Andric    return future<_Rp>(__h.get());
21520b57cec5SDimitry Andric}
21530b57cec5SDimitry Andric
2154e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2155e8d8bef9SDimitry Andric
21560b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
2157480093f4SDimitry Andricclass _LIBCPP_HIDDEN __async_func
21580b57cec5SDimitry Andric{
21590b57cec5SDimitry Andric    tuple<_Fp, _Args...> __f_;
21600b57cec5SDimitry Andric
21610b57cec5SDimitry Andricpublic:
21620b57cec5SDimitry Andric    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
21630b57cec5SDimitry Andric
2164*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
21650b57cec5SDimitry Andric    explicit __async_func(_Fp&& __f, _Args&&... __args)
2166*5f757f3fSDimitry Andric        : __f_(std::move(__f), std::move(__args)...) {}
21670b57cec5SDimitry Andric
2168*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2169*5f757f3fSDimitry Andric    __async_func(__async_func&& __f) : __f_(std::move(__f.__f_)) {}
21700b57cec5SDimitry Andric
217106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI _Rp operator()()
21720b57cec5SDimitry Andric    {
21730b57cec5SDimitry Andric        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
21740b57cec5SDimitry Andric        return __execute(_Index());
21750b57cec5SDimitry Andric    }
21760b57cec5SDimitry Andricprivate:
21770b57cec5SDimitry Andric    template <size_t ..._Indices>
217806c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI _Rp
21790b57cec5SDimitry Andric    __execute(__tuple_indices<_Indices...>)
21800b57cec5SDimitry Andric    {
2181*5f757f3fSDimitry Andric        return std::__invoke(std::move(std::get<0>(__f_)), std::move(std::get<_Indices>(__f_))...);
21820b57cec5SDimitry Andric    }
21830b57cec5SDimitry Andric};
21840b57cec5SDimitry Andric
2185*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool __does_policy_contain(launch __policy, launch __value )
21860b57cec5SDimitry Andric{ return (int(__policy) & int(__value)) != 0; }
21870b57cec5SDimitry Andric
21880b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
2189bdd1243dSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
219006c3fb27SDimitry Andricfuture<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
21910b57cec5SDimitry Andricasync(launch __policy, _Fp&& __f, _Args&&... __args)
21920b57cec5SDimitry Andric{
219306c3fb27SDimitry Andric    typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF;
21940b57cec5SDimitry Andric    typedef typename _BF::_Rp _Rp;
21950b57cec5SDimitry Andric
219606c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
21970b57cec5SDimitry Andric    try
21980b57cec5SDimitry Andric    {
21990b57cec5SDimitry Andric#endif
22000b57cec5SDimitry Andric        if (__does_policy_contain(__policy, launch::async))
2201*5f757f3fSDimitry Andric        return std::__make_async_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)),
2202*5f757f3fSDimitry Andric                                                        _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...));
220306c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
22040b57cec5SDimitry Andric    }
22050b57cec5SDimitry Andric    catch ( ... ) { if (__policy == launch::async) throw ; }
22060b57cec5SDimitry Andric#endif
22070b57cec5SDimitry Andric
22080b57cec5SDimitry Andric    if (__does_policy_contain(__policy, launch::deferred))
2209*5f757f3fSDimitry Andric        return std::__make_deferred_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)),
2210*5f757f3fSDimitry Andric                                                           _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...));
22110b57cec5SDimitry Andric    return future<_Rp>{};
22120b57cec5SDimitry Andric}
22130b57cec5SDimitry Andric
22140b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
2215*5f757f3fSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
221606c3fb27SDimitry Andricfuture<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
22170b57cec5SDimitry Andricasync(_Fp&& __f, _Args&&... __args)
22180b57cec5SDimitry Andric{
2219*5f757f3fSDimitry Andric    return std::async(launch::any, std::forward<_Fp>(__f),
2220*5f757f3fSDimitry Andric                                    std::forward<_Args>(__args)...);
22210b57cec5SDimitry Andric}
22220b57cec5SDimitry Andric
2223e8d8bef9SDimitry Andric#endif // C++03
22240b57cec5SDimitry Andric
22250b57cec5SDimitry Andric// shared_future
22260b57cec5SDimitry Andric
22270b57cec5SDimitry Andrictemplate <class _Rp>
22280b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future
22290b57cec5SDimitry Andric{
22300b57cec5SDimitry Andric    __assoc_state<_Rp>* __state_;
22310b57cec5SDimitry Andric
22320b57cec5SDimitry Andricpublic:
2233*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
22340b57cec5SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
2235*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
22360b57cec5SDimitry Andric    shared_future(const shared_future& __rhs)  _NOEXCEPT : __state_(__rhs.__state_)
22370b57cec5SDimitry Andric        {if (__state_) __state_->__add_shared();}
2238*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
22390b57cec5SDimitry Andric    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
22400b57cec5SDimitry Andric        {__f.__state_ = nullptr;}
2241*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
22420b57cec5SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
22430b57cec5SDimitry Andric        {__rhs.__state_ = nullptr;}
224406c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~shared_future();
224506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
2246*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
22470b57cec5SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
22480b57cec5SDimitry Andric        {
2249*5f757f3fSDimitry Andric            shared_future(std::move(__rhs)).swap(*this);
22500b57cec5SDimitry Andric            return *this;
22510b57cec5SDimitry Andric        }
22520b57cec5SDimitry Andric
22530b57cec5SDimitry Andric    // retrieving the value
2254*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
22550b57cec5SDimitry Andric    const _Rp& get() const {return __state_->copy();}
22560b57cec5SDimitry Andric
2257*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2258*5f757f3fSDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {std::swap(__state_, __rhs.__state_);}
22590b57cec5SDimitry Andric
22600b57cec5SDimitry Andric    // functions to check state
2261*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
22620b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
22630b57cec5SDimitry Andric
2264*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
22650b57cec5SDimitry Andric    void wait() const {__state_->wait();}
22660b57cec5SDimitry Andric    template <class _Rep, class _Period>
2267*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
22680b57cec5SDimitry Andric        future_status
22690b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
22700b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
22710b57cec5SDimitry Andric    template <class _Clock, class _Duration>
2272*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
22730b57cec5SDimitry Andric        future_status
22740b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
22750b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
22760b57cec5SDimitry Andric};
22770b57cec5SDimitry Andric
22780b57cec5SDimitry Andrictemplate <class _Rp>
22790b57cec5SDimitry Andricshared_future<_Rp>::~shared_future()
22800b57cec5SDimitry Andric{
22810b57cec5SDimitry Andric    if (__state_)
22820b57cec5SDimitry Andric        __state_->__release_shared();
22830b57cec5SDimitry Andric}
22840b57cec5SDimitry Andric
22850b57cec5SDimitry Andrictemplate <class _Rp>
22860b57cec5SDimitry Andricshared_future<_Rp>&
22870b57cec5SDimitry Andricshared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
22880b57cec5SDimitry Andric{
22890b57cec5SDimitry Andric    if (__rhs.__state_)
22900b57cec5SDimitry Andric        __rhs.__state_->__add_shared();
22910b57cec5SDimitry Andric    if (__state_)
22920b57cec5SDimitry Andric        __state_->__release_shared();
22930b57cec5SDimitry Andric    __state_ = __rhs.__state_;
22940b57cec5SDimitry Andric    return *this;
22950b57cec5SDimitry Andric}
22960b57cec5SDimitry Andric
22970b57cec5SDimitry Andrictemplate <class _Rp>
22980b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
22990b57cec5SDimitry Andric{
23000b57cec5SDimitry Andric    __assoc_state<_Rp&>* __state_;
23010b57cec5SDimitry Andric
23020b57cec5SDimitry Andricpublic:
2303*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23040b57cec5SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
2305*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23060b57cec5SDimitry Andric    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
23070b57cec5SDimitry Andric        {if (__state_) __state_->__add_shared();}
2308*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23090b57cec5SDimitry Andric    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
23100b57cec5SDimitry Andric        {__f.__state_ = nullptr;}
2311*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23120b57cec5SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
23130b57cec5SDimitry Andric        {__rhs.__state_ = nullptr;}
231406c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI ~shared_future();
231506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs);
2316*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23170b57cec5SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
23180b57cec5SDimitry Andric        {
2319*5f757f3fSDimitry Andric            shared_future(std::move(__rhs)).swap(*this);
23200b57cec5SDimitry Andric            return *this;
23210b57cec5SDimitry Andric        }
23220b57cec5SDimitry Andric
23230b57cec5SDimitry Andric    // retrieving the value
2324*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23250b57cec5SDimitry Andric    _Rp& get() const {return __state_->copy();}
23260b57cec5SDimitry Andric
2327*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2328*5f757f3fSDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {std::swap(__state_, __rhs.__state_);}
23290b57cec5SDimitry Andric
23300b57cec5SDimitry Andric    // functions to check state
2331*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23320b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
23330b57cec5SDimitry Andric
2334*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23350b57cec5SDimitry Andric    void wait() const {__state_->wait();}
23360b57cec5SDimitry Andric    template <class _Rep, class _Period>
2337*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
23380b57cec5SDimitry Andric        future_status
23390b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
23400b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
23410b57cec5SDimitry Andric    template <class _Clock, class _Duration>
2342*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
23430b57cec5SDimitry Andric        future_status
23440b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
23450b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
23460b57cec5SDimitry Andric};
23470b57cec5SDimitry Andric
23480b57cec5SDimitry Andrictemplate <class _Rp>
23490b57cec5SDimitry Andricshared_future<_Rp&>::~shared_future()
23500b57cec5SDimitry Andric{
23510b57cec5SDimitry Andric    if (__state_)
23520b57cec5SDimitry Andric        __state_->__release_shared();
23530b57cec5SDimitry Andric}
23540b57cec5SDimitry Andric
23550b57cec5SDimitry Andrictemplate <class _Rp>
23560b57cec5SDimitry Andricshared_future<_Rp&>&
23570b57cec5SDimitry Andricshared_future<_Rp&>::operator=(const shared_future& __rhs)
23580b57cec5SDimitry Andric{
23590b57cec5SDimitry Andric    if (__rhs.__state_)
23600b57cec5SDimitry Andric        __rhs.__state_->__add_shared();
23610b57cec5SDimitry Andric    if (__state_)
23620b57cec5SDimitry Andric        __state_->__release_shared();
23630b57cec5SDimitry Andric    __state_ = __rhs.__state_;
23640b57cec5SDimitry Andric    return *this;
23650b57cec5SDimitry Andric}
23660b57cec5SDimitry Andric
23670b57cec5SDimitry Andrictemplate <>
2368*5f757f3fSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI shared_future<void>
23690b57cec5SDimitry Andric{
23700b57cec5SDimitry Andric    __assoc_sub_state* __state_;
23710b57cec5SDimitry Andric
23720b57cec5SDimitry Andricpublic:
2373*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23740b57cec5SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
2375*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23760b57cec5SDimitry Andric    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
23770b57cec5SDimitry Andric        {if (__state_) __state_->__add_shared();}
2378*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23790b57cec5SDimitry Andric    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
23800b57cec5SDimitry Andric        {__f.__state_ = nullptr;}
2381*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23820b57cec5SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
23830b57cec5SDimitry Andric        {__rhs.__state_ = nullptr;}
23840b57cec5SDimitry Andric    ~shared_future();
23850b57cec5SDimitry Andric    shared_future& operator=(const shared_future& __rhs);
2386*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23870b57cec5SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
23880b57cec5SDimitry Andric        {
2389*5f757f3fSDimitry Andric            shared_future(std::move(__rhs)).swap(*this);
23900b57cec5SDimitry Andric            return *this;
23910b57cec5SDimitry Andric        }
23920b57cec5SDimitry Andric
23930b57cec5SDimitry Andric    // retrieving the value
2394*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
23950b57cec5SDimitry Andric    void get() const {__state_->copy();}
23960b57cec5SDimitry Andric
2397*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2398*5f757f3fSDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {std::swap(__state_, __rhs.__state_);}
23990b57cec5SDimitry Andric
24000b57cec5SDimitry Andric    // functions to check state
2401*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
24020b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
24030b57cec5SDimitry Andric
2404*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
24050b57cec5SDimitry Andric    void wait() const {__state_->wait();}
24060b57cec5SDimitry Andric    template <class _Rep, class _Period>
2407*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
24080b57cec5SDimitry Andric        future_status
24090b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
24100b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
24110b57cec5SDimitry Andric    template <class _Clock, class _Duration>
2412*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
24130b57cec5SDimitry Andric        future_status
24140b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
24150b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
24160b57cec5SDimitry Andric};
24170b57cec5SDimitry Andric
24180b57cec5SDimitry Andrictemplate <class _Rp>
2419*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
24200b57cec5SDimitry Andricvoid
24210b57cec5SDimitry Andricswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
24220b57cec5SDimitry Andric{
24230b57cec5SDimitry Andric    __x.swap(__y);
24240b57cec5SDimitry Andric}
24250b57cec5SDimitry Andric
24260b57cec5SDimitry Andrictemplate <class _Rp>
24270b57cec5SDimitry Andricinline
24280b57cec5SDimitry Andricshared_future<_Rp>
24290b57cec5SDimitry Andricfuture<_Rp>::share() _NOEXCEPT
24300b57cec5SDimitry Andric{
2431*5f757f3fSDimitry Andric    return shared_future<_Rp>(std::move(*this));
24320b57cec5SDimitry Andric}
24330b57cec5SDimitry Andric
24340b57cec5SDimitry Andrictemplate <class _Rp>
24350b57cec5SDimitry Andricinline
24360b57cec5SDimitry Andricshared_future<_Rp&>
24370b57cec5SDimitry Andricfuture<_Rp&>::share() _NOEXCEPT
24380b57cec5SDimitry Andric{
2439*5f757f3fSDimitry Andric    return shared_future<_Rp&>(std::move(*this));
24400b57cec5SDimitry Andric}
24410b57cec5SDimitry Andric
24420b57cec5SDimitry Andricinline
24430b57cec5SDimitry Andricshared_future<void>
24440b57cec5SDimitry Andricfuture<void>::share() _NOEXCEPT
24450b57cec5SDimitry Andric{
2446*5f757f3fSDimitry Andric    return shared_future<void>(std::move(*this));
24470b57cec5SDimitry Andric}
24480b57cec5SDimitry Andric
24490b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
24500b57cec5SDimitry Andric
2451bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
2452bdd1243dSDimitry Andric#  include <chrono>
2453bdd1243dSDimitry Andric#endif
2454bdd1243dSDimitry Andric
245506c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
245606c3fb27SDimitry Andric#  include <atomic>
245706c3fb27SDimitry Andric#  include <cstdlib>
245806c3fb27SDimitry Andric#  include <exception>
2459*5f757f3fSDimitry Andric#  include <iosfwd>
246006c3fb27SDimitry Andric#  include <system_error>
246106c3fb27SDimitry Andric#endif
246206c3fb27SDimitry Andric
24630b57cec5SDimitry Andric#endif // _LIBCPP_FUTURE
2464