17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===--------------------------- future -----------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP_FUTURE 127a984708SDavid Chisnall#define _LIBCPP_FUTURE 137a984708SDavid Chisnall 147a984708SDavid Chisnall/* 157a984708SDavid Chisnall future synopsis 167a984708SDavid Chisnall 177a984708SDavid Chisnallnamespace std 187a984708SDavid Chisnall{ 197a984708SDavid Chisnall 207a984708SDavid Chisnallenum class future_errc 217a984708SDavid Chisnall{ 224f7ab58eSDimitry Andric future_already_retrieved = 1, 237a984708SDavid Chisnall promise_already_satisfied, 244f7ab58eSDimitry Andric no_state, 254f7ab58eSDimitry Andric broken_promise 267a984708SDavid Chisnall}; 277a984708SDavid Chisnall 287a984708SDavid Chisnallenum class launch 297a984708SDavid Chisnall{ 307a984708SDavid Chisnall async = 1, 317a984708SDavid Chisnall deferred = 2, 327a984708SDavid Chisnall any = async | deferred 337a984708SDavid Chisnall}; 347a984708SDavid Chisnall 357a984708SDavid Chisnallenum class future_status 367a984708SDavid Chisnall{ 377a984708SDavid Chisnall ready, 387a984708SDavid Chisnall timeout, 397a984708SDavid Chisnall deferred 407a984708SDavid Chisnall}; 417a984708SDavid Chisnall 427a984708SDavid Chisnalltemplate <> struct is_error_code_enum<future_errc> : public true_type { }; 43936e9439SDimitry Andricerror_code make_error_code(future_errc e) noexcept; 44936e9439SDimitry Andricerror_condition make_error_condition(future_errc e) noexcept; 457a984708SDavid Chisnall 46936e9439SDimitry Andricconst error_category& future_category() noexcept; 477a984708SDavid Chisnall 487a984708SDavid Chisnallclass future_error 497a984708SDavid Chisnall : public logic_error 507a984708SDavid Chisnall{ 517a984708SDavid Chisnallpublic: 527a984708SDavid Chisnall future_error(error_code ec); // exposition only 53aed8d94eSDimitry Andric explicit future_error(future_errc); // C++17 54936e9439SDimitry Andric const error_code& code() const noexcept; 55936e9439SDimitry Andric const char* what() const noexcept; 567a984708SDavid Chisnall}; 577a984708SDavid Chisnall 587a984708SDavid Chisnalltemplate <class R> 597a984708SDavid Chisnallclass promise 607a984708SDavid Chisnall{ 617a984708SDavid Chisnallpublic: 627a984708SDavid Chisnall promise(); 637a984708SDavid Chisnall template <class Allocator> 647a984708SDavid Chisnall promise(allocator_arg_t, const Allocator& a); 65936e9439SDimitry Andric promise(promise&& rhs) noexcept; 667a984708SDavid Chisnall promise(const promise& rhs) = delete; 677a984708SDavid Chisnall ~promise(); 687a984708SDavid Chisnall 697a984708SDavid Chisnall // assignment 70936e9439SDimitry Andric promise& operator=(promise&& rhs) noexcept; 717a984708SDavid Chisnall promise& operator=(const promise& rhs) = delete; 72936e9439SDimitry Andric void swap(promise& other) noexcept; 737a984708SDavid Chisnall 747a984708SDavid Chisnall // retrieving the result 757a984708SDavid Chisnall future<R> get_future(); 767a984708SDavid Chisnall 777a984708SDavid Chisnall // setting the result 787a984708SDavid Chisnall void set_value(const R& r); 797a984708SDavid Chisnall void set_value(R&& r); 807a984708SDavid Chisnall void set_exception(exception_ptr p); 817a984708SDavid Chisnall 827a984708SDavid Chisnall // setting the result with deferred notification 837a984708SDavid Chisnall void set_value_at_thread_exit(const R& r); 847a984708SDavid Chisnall void set_value_at_thread_exit(R&& r); 857a984708SDavid Chisnall void set_exception_at_thread_exit(exception_ptr p); 867a984708SDavid Chisnall}; 877a984708SDavid Chisnall 887a984708SDavid Chisnalltemplate <class R> 897a984708SDavid Chisnallclass promise<R&> 907a984708SDavid Chisnall{ 917a984708SDavid Chisnallpublic: 927a984708SDavid Chisnall promise(); 937a984708SDavid Chisnall template <class Allocator> 947a984708SDavid Chisnall promise(allocator_arg_t, const Allocator& a); 95936e9439SDimitry Andric promise(promise&& rhs) noexcept; 967a984708SDavid Chisnall promise(const promise& rhs) = delete; 977a984708SDavid Chisnall ~promise(); 987a984708SDavid Chisnall 997a984708SDavid Chisnall // assignment 100936e9439SDimitry Andric promise& operator=(promise&& rhs) noexcept; 1017a984708SDavid Chisnall promise& operator=(const promise& rhs) = delete; 102936e9439SDimitry Andric void swap(promise& other) noexcept; 1037a984708SDavid Chisnall 1047a984708SDavid Chisnall // retrieving the result 1057a984708SDavid Chisnall future<R&> get_future(); 1067a984708SDavid Chisnall 1077a984708SDavid Chisnall // setting the result 1087a984708SDavid Chisnall void set_value(R& r); 1097a984708SDavid Chisnall void set_exception(exception_ptr p); 1107a984708SDavid Chisnall 1117a984708SDavid Chisnall // setting the result with deferred notification 1127a984708SDavid Chisnall void set_value_at_thread_exit(R&); 1137a984708SDavid Chisnall void set_exception_at_thread_exit(exception_ptr p); 1147a984708SDavid Chisnall}; 1157a984708SDavid Chisnall 1167a984708SDavid Chisnalltemplate <> 1177a984708SDavid Chisnallclass promise<void> 1187a984708SDavid Chisnall{ 1197a984708SDavid Chisnallpublic: 1207a984708SDavid Chisnall promise(); 1217a984708SDavid Chisnall template <class Allocator> 1227a984708SDavid Chisnall promise(allocator_arg_t, const Allocator& a); 123936e9439SDimitry Andric promise(promise&& rhs) noexcept; 1247a984708SDavid Chisnall promise(const promise& rhs) = delete; 1257a984708SDavid Chisnall ~promise(); 1267a984708SDavid Chisnall 1277a984708SDavid Chisnall // assignment 128936e9439SDimitry Andric promise& operator=(promise&& rhs) noexcept; 1297a984708SDavid Chisnall promise& operator=(const promise& rhs) = delete; 130936e9439SDimitry Andric void swap(promise& other) noexcept; 1317a984708SDavid Chisnall 1327a984708SDavid Chisnall // retrieving the result 1337a984708SDavid Chisnall future<void> get_future(); 1347a984708SDavid Chisnall 1357a984708SDavid Chisnall // setting the result 1367a984708SDavid Chisnall void set_value(); 1377a984708SDavid Chisnall void set_exception(exception_ptr p); 1387a984708SDavid Chisnall 1397a984708SDavid Chisnall // setting the result with deferred notification 1407a984708SDavid Chisnall void set_value_at_thread_exit(); 1417a984708SDavid Chisnall void set_exception_at_thread_exit(exception_ptr p); 1427a984708SDavid Chisnall}; 1437a984708SDavid Chisnall 144936e9439SDimitry Andrictemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept; 1457a984708SDavid Chisnall 1467a984708SDavid Chisnalltemplate <class R, class Alloc> 1477a984708SDavid Chisnall struct uses_allocator<promise<R>, Alloc> : public true_type {}; 1487a984708SDavid Chisnall 1497a984708SDavid Chisnalltemplate <class R> 1507a984708SDavid Chisnallclass future 1517a984708SDavid Chisnall{ 1527a984708SDavid Chisnallpublic: 153936e9439SDimitry Andric future() noexcept; 154936e9439SDimitry Andric future(future&&) noexcept; 1557a984708SDavid Chisnall future(const future& rhs) = delete; 1567a984708SDavid Chisnall ~future(); 1577a984708SDavid Chisnall future& operator=(const future& rhs) = delete; 158936e9439SDimitry Andric future& operator=(future&&) noexcept; 159540d2a8bSDimitry Andric shared_future<R> share() noexcept; 1607a984708SDavid Chisnall 1617a984708SDavid Chisnall // retrieving the value 1627a984708SDavid Chisnall R get(); 1637a984708SDavid Chisnall 1647a984708SDavid Chisnall // functions to check state 165936e9439SDimitry Andric bool valid() const noexcept; 1667a984708SDavid Chisnall 1677a984708SDavid Chisnall void wait() const; 1687a984708SDavid Chisnall template <class Rep, class Period> 1697a984708SDavid Chisnall future_status 1707a984708SDavid Chisnall wait_for(const chrono::duration<Rep, Period>& rel_time) const; 1717a984708SDavid Chisnall template <class Clock, class Duration> 1727a984708SDavid Chisnall future_status 1737a984708SDavid Chisnall wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 1747a984708SDavid Chisnall}; 1757a984708SDavid Chisnall 1767a984708SDavid Chisnalltemplate <class R> 1777a984708SDavid Chisnallclass future<R&> 1787a984708SDavid Chisnall{ 1797a984708SDavid Chisnallpublic: 180936e9439SDimitry Andric future() noexcept; 181936e9439SDimitry Andric future(future&&) noexcept; 1827a984708SDavid Chisnall future(const future& rhs) = delete; 1837a984708SDavid Chisnall ~future(); 1847a984708SDavid Chisnall future& operator=(const future& rhs) = delete; 185936e9439SDimitry Andric future& operator=(future&&) noexcept; 186540d2a8bSDimitry Andric shared_future<R&> share() noexcept; 1877a984708SDavid Chisnall 1887a984708SDavid Chisnall // retrieving the value 1897a984708SDavid Chisnall R& get(); 1907a984708SDavid Chisnall 1917a984708SDavid Chisnall // functions to check state 192936e9439SDimitry Andric bool valid() const noexcept; 1937a984708SDavid Chisnall 1947a984708SDavid Chisnall void wait() const; 1957a984708SDavid Chisnall template <class Rep, class Period> 1967a984708SDavid Chisnall future_status 1977a984708SDavid Chisnall wait_for(const chrono::duration<Rep, Period>& rel_time) const; 1987a984708SDavid Chisnall template <class Clock, class Duration> 1997a984708SDavid Chisnall future_status 2007a984708SDavid Chisnall wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 2017a984708SDavid Chisnall}; 2027a984708SDavid Chisnall 2037a984708SDavid Chisnalltemplate <> 2047a984708SDavid Chisnallclass future<void> 2057a984708SDavid Chisnall{ 2067a984708SDavid Chisnallpublic: 207936e9439SDimitry Andric future() noexcept; 208936e9439SDimitry Andric future(future&&) noexcept; 2097a984708SDavid Chisnall future(const future& rhs) = delete; 2107a984708SDavid Chisnall ~future(); 2117a984708SDavid Chisnall future& operator=(const future& rhs) = delete; 212936e9439SDimitry Andric future& operator=(future&&) noexcept; 213540d2a8bSDimitry Andric shared_future<void> share() noexcept; 2147a984708SDavid Chisnall 2157a984708SDavid Chisnall // retrieving the value 2167a984708SDavid Chisnall void get(); 2177a984708SDavid Chisnall 2187a984708SDavid Chisnall // functions to check state 219936e9439SDimitry Andric bool valid() const noexcept; 2207a984708SDavid Chisnall 2217a984708SDavid Chisnall void wait() const; 2227a984708SDavid Chisnall template <class Rep, class Period> 2237a984708SDavid Chisnall future_status 2247a984708SDavid Chisnall wait_for(const chrono::duration<Rep, Period>& rel_time) const; 2257a984708SDavid Chisnall template <class Clock, class Duration> 2267a984708SDavid Chisnall future_status 2277a984708SDavid Chisnall wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 2287a984708SDavid Chisnall}; 2297a984708SDavid Chisnall 2307a984708SDavid Chisnalltemplate <class R> 2317a984708SDavid Chisnallclass shared_future 2327a984708SDavid Chisnall{ 2337a984708SDavid Chisnallpublic: 234936e9439SDimitry Andric shared_future() noexcept; 2357a984708SDavid Chisnall shared_future(const shared_future& rhs); 236936e9439SDimitry Andric shared_future(future<R>&&) noexcept; 237936e9439SDimitry Andric shared_future(shared_future&& rhs) noexcept; 2387a984708SDavid Chisnall ~shared_future(); 2397a984708SDavid Chisnall shared_future& operator=(const shared_future& rhs); 240936e9439SDimitry Andric shared_future& operator=(shared_future&& rhs) noexcept; 2417a984708SDavid Chisnall 2427a984708SDavid Chisnall // retrieving the value 2437a984708SDavid Chisnall const R& get() const; 2447a984708SDavid Chisnall 2457a984708SDavid Chisnall // functions to check state 246936e9439SDimitry Andric bool valid() const noexcept; 2477a984708SDavid Chisnall 2487a984708SDavid Chisnall void wait() const; 2497a984708SDavid Chisnall template <class Rep, class Period> 2507a984708SDavid Chisnall future_status 2517a984708SDavid Chisnall wait_for(const chrono::duration<Rep, Period>& rel_time) const; 2527a984708SDavid Chisnall template <class Clock, class Duration> 2537a984708SDavid Chisnall future_status 2547a984708SDavid Chisnall wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 2557a984708SDavid Chisnall}; 2567a984708SDavid Chisnall 2577a984708SDavid Chisnalltemplate <class R> 2587a984708SDavid Chisnallclass shared_future<R&> 2597a984708SDavid Chisnall{ 2607a984708SDavid Chisnallpublic: 261936e9439SDimitry Andric shared_future() noexcept; 2627a984708SDavid Chisnall shared_future(const shared_future& rhs); 263936e9439SDimitry Andric shared_future(future<R&>&&) noexcept; 264936e9439SDimitry Andric shared_future(shared_future&& rhs) noexcept; 2657a984708SDavid Chisnall ~shared_future(); 2667a984708SDavid Chisnall shared_future& operator=(const shared_future& rhs); 267936e9439SDimitry Andric shared_future& operator=(shared_future&& rhs) noexcept; 2687a984708SDavid Chisnall 2697a984708SDavid Chisnall // retrieving the value 2707a984708SDavid Chisnall R& get() const; 2717a984708SDavid Chisnall 2727a984708SDavid Chisnall // functions to check state 273936e9439SDimitry Andric bool valid() const noexcept; 2747a984708SDavid Chisnall 2757a984708SDavid Chisnall void wait() const; 2767a984708SDavid Chisnall template <class Rep, class Period> 2777a984708SDavid Chisnall future_status 2787a984708SDavid Chisnall wait_for(const chrono::duration<Rep, Period>& rel_time) const; 2797a984708SDavid Chisnall template <class Clock, class Duration> 2807a984708SDavid Chisnall future_status 2817a984708SDavid Chisnall wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 2827a984708SDavid Chisnall}; 2837a984708SDavid Chisnall 2847a984708SDavid Chisnalltemplate <> 2857a984708SDavid Chisnallclass shared_future<void> 2867a984708SDavid Chisnall{ 2877a984708SDavid Chisnallpublic: 288936e9439SDimitry Andric shared_future() noexcept; 2897a984708SDavid Chisnall shared_future(const shared_future& rhs); 290936e9439SDimitry Andric shared_future(future<void>&&) noexcept; 291936e9439SDimitry Andric shared_future(shared_future&& rhs) noexcept; 2927a984708SDavid Chisnall ~shared_future(); 2937a984708SDavid Chisnall shared_future& operator=(const shared_future& rhs); 294936e9439SDimitry Andric shared_future& operator=(shared_future&& rhs) noexcept; 2957a984708SDavid Chisnall 2967a984708SDavid Chisnall // retrieving the value 2977a984708SDavid Chisnall void get() const; 2987a984708SDavid Chisnall 2997a984708SDavid Chisnall // functions to check state 300936e9439SDimitry Andric bool valid() const noexcept; 3017a984708SDavid Chisnall 3027a984708SDavid Chisnall void wait() const; 3037a984708SDavid Chisnall template <class Rep, class Period> 3047a984708SDavid Chisnall future_status 3057a984708SDavid Chisnall wait_for(const chrono::duration<Rep, Period>& rel_time) const; 3067a984708SDavid Chisnall template <class Clock, class Duration> 3077a984708SDavid Chisnall future_status 3087a984708SDavid Chisnall wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 3097a984708SDavid Chisnall}; 3107a984708SDavid Chisnall 3117a984708SDavid Chisnalltemplate <class F, class... Args> 3124f7ab58eSDimitry Andric future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 3137a984708SDavid Chisnall async(F&& f, Args&&... args); 3147a984708SDavid Chisnall 3157a984708SDavid Chisnalltemplate <class F, class... Args> 3164f7ab58eSDimitry Andric future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 3177a984708SDavid Chisnall async(launch policy, F&& f, Args&&... args); 3187a984708SDavid Chisnall 3197a984708SDavid Chisnalltemplate <class> class packaged_task; // undefined 3207a984708SDavid Chisnall 3217a984708SDavid Chisnalltemplate <class R, class... ArgTypes> 3227a984708SDavid Chisnallclass packaged_task<R(ArgTypes...)> 3237a984708SDavid Chisnall{ 3247a984708SDavid Chisnallpublic: 3257c82a1ecSDimitry Andric typedef R result_type; // extension 3267a984708SDavid Chisnall 3277a984708SDavid Chisnall // construction and destruction 328936e9439SDimitry Andric packaged_task() noexcept; 3297a984708SDavid Chisnall template <class F> 3307a984708SDavid Chisnall explicit packaged_task(F&& f); 3317a984708SDavid Chisnall template <class F, class Allocator> 332854fa44bSDimitry Andric packaged_task(allocator_arg_t, const Allocator& a, F&& f); 3337a984708SDavid Chisnall ~packaged_task(); 3347a984708SDavid Chisnall 3357a984708SDavid Chisnall // no copy 336936e9439SDimitry Andric packaged_task(const packaged_task&) = delete; 337936e9439SDimitry Andric packaged_task& operator=(const packaged_task&) = delete; 3387a984708SDavid Chisnall 3397a984708SDavid Chisnall // move support 340936e9439SDimitry Andric packaged_task(packaged_task&& other) noexcept; 341936e9439SDimitry Andric packaged_task& operator=(packaged_task&& other) noexcept; 342936e9439SDimitry Andric void swap(packaged_task& other) noexcept; 3437a984708SDavid Chisnall 344936e9439SDimitry Andric bool valid() const noexcept; 3457a984708SDavid Chisnall 3467a984708SDavid Chisnall // result retrieval 3477a984708SDavid Chisnall future<R> get_future(); 3487a984708SDavid Chisnall 3497a984708SDavid Chisnall // execution 3507a984708SDavid Chisnall void operator()(ArgTypes... ); 3517a984708SDavid Chisnall void make_ready_at_thread_exit(ArgTypes...); 3527a984708SDavid Chisnall 3537a984708SDavid Chisnall void reset(); 3547a984708SDavid Chisnall}; 3557a984708SDavid Chisnall 3567a984708SDavid Chisnalltemplate <class R> 357936e9439SDimitry Andric void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept; 3587a984708SDavid Chisnall 3597a984708SDavid Chisnalltemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; 3607a984708SDavid Chisnall 3617a984708SDavid Chisnall} // std 3627a984708SDavid Chisnall 3637a984708SDavid Chisnall*/ 3647a984708SDavid Chisnall 3657a984708SDavid Chisnall#include <__config> 3667a984708SDavid Chisnall#include <system_error> 3677a984708SDavid Chisnall#include <memory> 3687a984708SDavid Chisnall#include <chrono> 3697a984708SDavid Chisnall#include <exception> 3707a984708SDavid Chisnall#include <mutex> 3717a984708SDavid Chisnall#include <thread> 3727a984708SDavid Chisnall 3737a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 3747a984708SDavid Chisnall#pragma GCC system_header 3757a984708SDavid Chisnall#endif 3767a984708SDavid Chisnall 377d72607e9SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS 378d72607e9SDimitry Andric#error <future> is not supported on this single threaded system 379d72607e9SDimitry Andric#else // !_LIBCPP_HAS_NO_THREADS 380d72607e9SDimitry Andric 3817a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD 3827a984708SDavid Chisnall 3837a984708SDavid Chisnall//enum class future_errc 38494e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM(future_errc) 3857a984708SDavid Chisnall{ 3864f7ab58eSDimitry Andric future_already_retrieved = 1, 3877a984708SDavid Chisnall promise_already_satisfied, 3884f7ab58eSDimitry Andric no_state, 3894f7ab58eSDimitry Andric broken_promise 3907a984708SDavid Chisnall}; 39194e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc) 3927a984708SDavid Chisnall 3937a984708SDavid Chisnalltemplate <> 394aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {}; 3957a984708SDavid Chisnall 39694e3ee44SDavid Chisnall#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS 39794e3ee44SDavid Chisnalltemplate <> 398aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { }; 39994e3ee44SDavid Chisnall#endif 40094e3ee44SDavid Chisnall 4017a984708SDavid Chisnall//enum class launch 40294e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM(launch) 4037a984708SDavid Chisnall{ 4047a984708SDavid Chisnall async = 1, 4057a984708SDavid Chisnall deferred = 2, 4067a984708SDavid Chisnall any = async | deferred 4077a984708SDavid Chisnall}; 40894e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch) 4097a984708SDavid Chisnall 4104bab9fd9SDavid Chisnall#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS 4114bab9fd9SDavid Chisnall 4124ba319b5SDimitry Andric#ifdef _LIBCPP_UNDERLYING_TYPE 4134bab9fd9SDavid Chisnalltypedef underlying_type<launch>::type __launch_underlying_type; 4144bab9fd9SDavid Chisnall#else 4154bab9fd9SDavid Chisnalltypedef int __launch_underlying_type; 4164bab9fd9SDavid Chisnall#endif 4174bab9fd9SDavid Chisnall 4184bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 4194bab9fd9SDavid Chisnall_LIBCPP_CONSTEXPR 4204bab9fd9SDavid Chisnalllaunch 4214bab9fd9SDavid Chisnalloperator&(launch __x, launch __y) 4224bab9fd9SDavid Chisnall{ 4234bab9fd9SDavid Chisnall return static_cast<launch>(static_cast<__launch_underlying_type>(__x) & 4244bab9fd9SDavid Chisnall static_cast<__launch_underlying_type>(__y)); 4254bab9fd9SDavid Chisnall} 4264bab9fd9SDavid Chisnall 4274bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 4284bab9fd9SDavid Chisnall_LIBCPP_CONSTEXPR 4294bab9fd9SDavid Chisnalllaunch 4304bab9fd9SDavid Chisnalloperator|(launch __x, launch __y) 4314bab9fd9SDavid Chisnall{ 4324bab9fd9SDavid Chisnall return static_cast<launch>(static_cast<__launch_underlying_type>(__x) | 4334bab9fd9SDavid Chisnall static_cast<__launch_underlying_type>(__y)); 4344bab9fd9SDavid Chisnall} 4354bab9fd9SDavid Chisnall 4364bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 4374bab9fd9SDavid Chisnall_LIBCPP_CONSTEXPR 4384bab9fd9SDavid Chisnalllaunch 4394bab9fd9SDavid Chisnalloperator^(launch __x, launch __y) 4404bab9fd9SDavid Chisnall{ 4414bab9fd9SDavid Chisnall return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^ 4424bab9fd9SDavid Chisnall static_cast<__launch_underlying_type>(__y)); 4434bab9fd9SDavid Chisnall} 4444bab9fd9SDavid Chisnall 4454bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 4464bab9fd9SDavid Chisnall_LIBCPP_CONSTEXPR 4474bab9fd9SDavid Chisnalllaunch 4484bab9fd9SDavid Chisnalloperator~(launch __x) 4494bab9fd9SDavid Chisnall{ 4504bab9fd9SDavid Chisnall return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3); 4514bab9fd9SDavid Chisnall} 4524bab9fd9SDavid Chisnall 4534bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 4544bab9fd9SDavid Chisnalllaunch& 4554bab9fd9SDavid Chisnalloperator&=(launch& __x, launch __y) 4564bab9fd9SDavid Chisnall{ 4574bab9fd9SDavid Chisnall __x = __x & __y; return __x; 4584bab9fd9SDavid Chisnall} 4594bab9fd9SDavid Chisnall 4604bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 4614bab9fd9SDavid Chisnalllaunch& 4624bab9fd9SDavid Chisnalloperator|=(launch& __x, launch __y) 4634bab9fd9SDavid Chisnall{ 4644bab9fd9SDavid Chisnall __x = __x | __y; return __x; 4654bab9fd9SDavid Chisnall} 4664bab9fd9SDavid Chisnall 4674bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 4684bab9fd9SDavid Chisnalllaunch& 4694bab9fd9SDavid Chisnalloperator^=(launch& __x, launch __y) 4704bab9fd9SDavid Chisnall{ 4714bab9fd9SDavid Chisnall __x = __x ^ __y; return __x; 4724bab9fd9SDavid Chisnall} 4734bab9fd9SDavid Chisnall 4744bab9fd9SDavid Chisnall#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS 4754bab9fd9SDavid Chisnall 4767a984708SDavid Chisnall//enum class future_status 47794e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM(future_status) 4787a984708SDavid Chisnall{ 4797a984708SDavid Chisnall ready, 4807a984708SDavid Chisnall timeout, 4817a984708SDavid Chisnall deferred 4827a984708SDavid Chisnall}; 48394e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status) 4847a984708SDavid Chisnall 4851bf9f7c1SDimitry Andric_LIBCPP_FUNC_VIS 486936e9439SDimitry Andricconst error_category& future_category() _NOEXCEPT; 4877a984708SDavid Chisnall 4887a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 4897a984708SDavid Chisnallerror_code 490936e9439SDimitry Andricmake_error_code(future_errc __e) _NOEXCEPT 4917a984708SDavid Chisnall{ 4927a984708SDavid Chisnall return error_code(static_cast<int>(__e), future_category()); 4937a984708SDavid Chisnall} 4947a984708SDavid Chisnall 4957a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 4967a984708SDavid Chisnallerror_condition 497936e9439SDimitry Andricmake_error_condition(future_errc __e) _NOEXCEPT 4987a984708SDavid Chisnall{ 4997a984708SDavid Chisnall return error_condition(static_cast<int>(__e), future_category()); 5007a984708SDavid Chisnall} 5017a984708SDavid Chisnall 5020f5676f4SDimitry Andricclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error 5037a984708SDavid Chisnall : public logic_error 5047a984708SDavid Chisnall{ 5057a984708SDavid Chisnall error_code __ec_; 5067a984708SDavid Chisnallpublic: 5077a984708SDavid Chisnall future_error(error_code __ec); 508aed8d94eSDimitry Andric#if _LIBCPP_STD_VERS > 14 509aed8d94eSDimitry Andric explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {} 510aed8d94eSDimitry Andric#endif 5117a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 512936e9439SDimitry Andric const error_code& code() const _NOEXCEPT {return __ec_;} 5137a984708SDavid Chisnall 5147a984708SDavid Chisnall virtual ~future_error() _NOEXCEPT; 5157a984708SDavid Chisnall}; 5167a984708SDavid Chisnall 5174ba319b5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 5180f5676f4SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 5190f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_FUTURE_ERROR 5200f5676f4SDimitry Andric#endif 5219729cf09SDimitry Andricvoid __throw_future_error(future_errc _Ev) 5229729cf09SDimitry Andric{ 5239729cf09SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 5249729cf09SDimitry Andric throw future_error(make_error_code(_Ev)); 5259729cf09SDimitry Andric#else 526aed8d94eSDimitry Andric ((void)_Ev); 527aed8d94eSDimitry Andric _VSTD::abort(); 5289729cf09SDimitry Andric#endif 5299729cf09SDimitry Andric} 5309729cf09SDimitry Andric 5310f5676f4SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state 5327a984708SDavid Chisnall : public __shared_count 5337a984708SDavid Chisnall{ 5347a984708SDavid Chisnallprotected: 5357a984708SDavid Chisnall exception_ptr __exception_; 5367a984708SDavid Chisnall mutable mutex __mut_; 5377a984708SDavid Chisnall mutable condition_variable __cv_; 5387a984708SDavid Chisnall unsigned __state_; 5397a984708SDavid Chisnall 5407a984708SDavid Chisnall virtual void __on_zero_shared() _NOEXCEPT; 5417a984708SDavid Chisnall void __sub_wait(unique_lock<mutex>& __lk); 5427a984708SDavid Chisnallpublic: 5437a984708SDavid Chisnall enum 5447a984708SDavid Chisnall { 5457a984708SDavid Chisnall __constructed = 1, 5467a984708SDavid Chisnall __future_attached = 2, 5477a984708SDavid Chisnall ready = 4, 5487a984708SDavid Chisnall deferred = 8 5497a984708SDavid Chisnall }; 5507a984708SDavid Chisnall 5517a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5527a984708SDavid Chisnall __assoc_sub_state() : __state_(0) {} 5537a984708SDavid Chisnall 5547a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5557a984708SDavid Chisnall bool __has_value() const 5567a984708SDavid Chisnall {return (__state_ & __constructed) || (__exception_ != nullptr);} 5577a984708SDavid Chisnall 5587a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 559*b5893f02SDimitry Andric void __attach_future() { 560cfdf2879SDavid Chisnall lock_guard<mutex> __lk(__mut_); 561*b5893f02SDimitry Andric bool __has_future_attached = (__state_ & __future_attached) != 0; 562*b5893f02SDimitry Andric if (__has_future_attached) 563*b5893f02SDimitry Andric __throw_future_error(future_errc::future_already_retrieved); 564*b5893f02SDimitry Andric this->__add_shared(); 565cfdf2879SDavid Chisnall __state_ |= __future_attached; 566cfdf2879SDavid Chisnall } 5677a984708SDavid Chisnall 5687a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5697a984708SDavid Chisnall void __set_deferred() {__state_ |= deferred;} 5707a984708SDavid Chisnall 5717a984708SDavid Chisnall void __make_ready(); 5727a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5734f7ab58eSDimitry Andric bool __is_ready() const {return (__state_ & ready) != 0;} 5747a984708SDavid Chisnall 5757a984708SDavid Chisnall void set_value(); 5767a984708SDavid Chisnall void set_value_at_thread_exit(); 5777a984708SDavid Chisnall 5787a984708SDavid Chisnall void set_exception(exception_ptr __p); 5797a984708SDavid Chisnall void set_exception_at_thread_exit(exception_ptr __p); 5807a984708SDavid Chisnall 5817a984708SDavid Chisnall void copy(); 5827a984708SDavid Chisnall 5837a984708SDavid Chisnall void wait(); 5847a984708SDavid Chisnall template <class _Rep, class _Period> 5857a984708SDavid Chisnall future_status 5869729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5877a984708SDavid Chisnall wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; 5887a984708SDavid Chisnall template <class _Clock, class _Duration> 589540d2a8bSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 5907a984708SDavid Chisnall future_status 5917a984708SDavid Chisnall wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const; 5927a984708SDavid Chisnall 5937a984708SDavid Chisnall virtual void __execute(); 5947a984708SDavid Chisnall}; 5957a984708SDavid Chisnall 5967a984708SDavid Chisnalltemplate <class _Clock, class _Duration> 5977a984708SDavid Chisnallfuture_status 5987a984708SDavid Chisnall__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 5997a984708SDavid Chisnall{ 6007a984708SDavid Chisnall unique_lock<mutex> __lk(__mut_); 6017a984708SDavid Chisnall if (__state_ & deferred) 6027a984708SDavid Chisnall return future_status::deferred; 6037a984708SDavid Chisnall while (!(__state_ & ready) && _Clock::now() < __abs_time) 6047a984708SDavid Chisnall __cv_.wait_until(__lk, __abs_time); 6057a984708SDavid Chisnall if (__state_ & ready) 6067a984708SDavid Chisnall return future_status::ready; 6077a984708SDavid Chisnall return future_status::timeout; 6087a984708SDavid Chisnall} 6097a984708SDavid Chisnall 6107a984708SDavid Chisnalltemplate <class _Rep, class _Period> 6119729cf09SDimitry Andricinline 6127a984708SDavid Chisnallfuture_status 6137a984708SDavid Chisnall__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 6147a984708SDavid Chisnall{ 6157a984708SDavid Chisnall return wait_until(chrono::steady_clock::now() + __rel_time); 6167a984708SDavid Chisnall} 6177a984708SDavid Chisnall 61894e3ee44SDavid Chisnalltemplate <class _Rp> 6190f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state 6207a984708SDavid Chisnall : public __assoc_sub_state 6217a984708SDavid Chisnall{ 6227a984708SDavid Chisnall typedef __assoc_sub_state base; 62394e3ee44SDavid Chisnall typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up; 6247a984708SDavid Chisnallprotected: 62594e3ee44SDavid Chisnall _Up __value_; 6267a984708SDavid Chisnall 6277a984708SDavid Chisnall virtual void __on_zero_shared() _NOEXCEPT; 6287a984708SDavid Chisnallpublic: 6297a984708SDavid Chisnall 6307a984708SDavid Chisnall template <class _Arg> 6317a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 6327a984708SDavid Chisnall void set_value(_Arg&& __arg); 6337a984708SDavid Chisnall#else 6347a984708SDavid Chisnall void set_value(_Arg& __arg); 6357a984708SDavid Chisnall#endif 6367a984708SDavid Chisnall 6377a984708SDavid Chisnall template <class _Arg> 6387a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 6397a984708SDavid Chisnall void set_value_at_thread_exit(_Arg&& __arg); 6407a984708SDavid Chisnall#else 6417a984708SDavid Chisnall void set_value_at_thread_exit(_Arg& __arg); 6427a984708SDavid Chisnall#endif 6437a984708SDavid Chisnall 64494e3ee44SDavid Chisnall _Rp move(); 64594e3ee44SDavid Chisnall typename add_lvalue_reference<_Rp>::type copy(); 6467a984708SDavid Chisnall}; 6477a984708SDavid Chisnall 64894e3ee44SDavid Chisnalltemplate <class _Rp> 6497a984708SDavid Chisnallvoid 65094e3ee44SDavid Chisnall__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT 6517a984708SDavid Chisnall{ 6527a984708SDavid Chisnall if (this->__state_ & base::__constructed) 65394e3ee44SDavid Chisnall reinterpret_cast<_Rp*>(&__value_)->~_Rp(); 6547a984708SDavid Chisnall delete this; 6557a984708SDavid Chisnall} 6567a984708SDavid Chisnall 65794e3ee44SDavid Chisnalltemplate <class _Rp> 6587a984708SDavid Chisnalltemplate <class _Arg> 6590f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_FUTURE 6607a984708SDavid Chisnallvoid 6617a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 66294e3ee44SDavid Chisnall__assoc_state<_Rp>::set_value(_Arg&& __arg) 6637a984708SDavid Chisnall#else 66494e3ee44SDavid Chisnall__assoc_state<_Rp>::set_value(_Arg& __arg) 6657a984708SDavid Chisnall#endif 6667a984708SDavid Chisnall{ 6677a984708SDavid Chisnall unique_lock<mutex> __lk(this->__mut_); 6687a984708SDavid Chisnall if (this->__has_value()) 6699729cf09SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 67094e3ee44SDavid Chisnall ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); 6717a984708SDavid Chisnall this->__state_ |= base::__constructed | base::ready; 6727a984708SDavid Chisnall __cv_.notify_all(); 6737a984708SDavid Chisnall} 6747a984708SDavid Chisnall 67594e3ee44SDavid Chisnalltemplate <class _Rp> 6767a984708SDavid Chisnalltemplate <class _Arg> 6777a984708SDavid Chisnallvoid 6787a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 67994e3ee44SDavid Chisnall__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) 6807a984708SDavid Chisnall#else 68194e3ee44SDavid Chisnall__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg) 6827a984708SDavid Chisnall#endif 6837a984708SDavid Chisnall{ 6847a984708SDavid Chisnall unique_lock<mutex> __lk(this->__mut_); 6857a984708SDavid Chisnall if (this->__has_value()) 6869729cf09SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 68794e3ee44SDavid Chisnall ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); 6887a984708SDavid Chisnall this->__state_ |= base::__constructed; 6897a984708SDavid Chisnall __thread_local_data()->__make_ready_at_thread_exit(this); 6907a984708SDavid Chisnall} 6917a984708SDavid Chisnall 69294e3ee44SDavid Chisnalltemplate <class _Rp> 69394e3ee44SDavid Chisnall_Rp 69494e3ee44SDavid Chisnall__assoc_state<_Rp>::move() 6957a984708SDavid Chisnall{ 6967a984708SDavid Chisnall unique_lock<mutex> __lk(this->__mut_); 6977a984708SDavid Chisnall this->__sub_wait(__lk); 6987a984708SDavid Chisnall if (this->__exception_ != nullptr) 6997a984708SDavid Chisnall rethrow_exception(this->__exception_); 70094e3ee44SDavid Chisnall return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_)); 7017a984708SDavid Chisnall} 7027a984708SDavid Chisnall 70394e3ee44SDavid Chisnalltemplate <class _Rp> 70494e3ee44SDavid Chisnalltypename add_lvalue_reference<_Rp>::type 70594e3ee44SDavid Chisnall__assoc_state<_Rp>::copy() 7067a984708SDavid Chisnall{ 7077a984708SDavid Chisnall unique_lock<mutex> __lk(this->__mut_); 7087a984708SDavid Chisnall this->__sub_wait(__lk); 7097a984708SDavid Chisnall if (this->__exception_ != nullptr) 7107a984708SDavid Chisnall rethrow_exception(this->__exception_); 71194e3ee44SDavid Chisnall return *reinterpret_cast<_Rp*>(&__value_); 7127a984708SDavid Chisnall} 7137a984708SDavid Chisnall 71494e3ee44SDavid Chisnalltemplate <class _Rp> 7150f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&> 7167a984708SDavid Chisnall : public __assoc_sub_state 7177a984708SDavid Chisnall{ 7187a984708SDavid Chisnall typedef __assoc_sub_state base; 71994e3ee44SDavid Chisnall typedef _Rp* _Up; 7207a984708SDavid Chisnallprotected: 72194e3ee44SDavid Chisnall _Up __value_; 7227a984708SDavid Chisnall 7237a984708SDavid Chisnall virtual void __on_zero_shared() _NOEXCEPT; 7247a984708SDavid Chisnallpublic: 7257a984708SDavid Chisnall 72694e3ee44SDavid Chisnall void set_value(_Rp& __arg); 72794e3ee44SDavid Chisnall void set_value_at_thread_exit(_Rp& __arg); 7287a984708SDavid Chisnall 72994e3ee44SDavid Chisnall _Rp& copy(); 7307a984708SDavid Chisnall}; 7317a984708SDavid Chisnall 73294e3ee44SDavid Chisnalltemplate <class _Rp> 7337a984708SDavid Chisnallvoid 73494e3ee44SDavid Chisnall__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT 7357a984708SDavid Chisnall{ 7367a984708SDavid Chisnall delete this; 7377a984708SDavid Chisnall} 7387a984708SDavid Chisnall 73994e3ee44SDavid Chisnalltemplate <class _Rp> 7407a984708SDavid Chisnallvoid 74194e3ee44SDavid Chisnall__assoc_state<_Rp&>::set_value(_Rp& __arg) 7427a984708SDavid Chisnall{ 7437a984708SDavid Chisnall unique_lock<mutex> __lk(this->__mut_); 7447a984708SDavid Chisnall if (this->__has_value()) 7459729cf09SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 7464f7ab58eSDimitry Andric __value_ = _VSTD::addressof(__arg); 7477a984708SDavid Chisnall this->__state_ |= base::__constructed | base::ready; 7487a984708SDavid Chisnall __cv_.notify_all(); 7497a984708SDavid Chisnall} 7507a984708SDavid Chisnall 75194e3ee44SDavid Chisnalltemplate <class _Rp> 7527a984708SDavid Chisnallvoid 75394e3ee44SDavid Chisnall__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) 7547a984708SDavid Chisnall{ 7557a984708SDavid Chisnall unique_lock<mutex> __lk(this->__mut_); 7567a984708SDavid Chisnall if (this->__has_value()) 7579729cf09SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 7584f7ab58eSDimitry Andric __value_ = _VSTD::addressof(__arg); 7597a984708SDavid Chisnall this->__state_ |= base::__constructed; 7607a984708SDavid Chisnall __thread_local_data()->__make_ready_at_thread_exit(this); 7617a984708SDavid Chisnall} 7627a984708SDavid Chisnall 76394e3ee44SDavid Chisnalltemplate <class _Rp> 76494e3ee44SDavid Chisnall_Rp& 76594e3ee44SDavid Chisnall__assoc_state<_Rp&>::copy() 7667a984708SDavid Chisnall{ 7677a984708SDavid Chisnall unique_lock<mutex> __lk(this->__mut_); 7687a984708SDavid Chisnall this->__sub_wait(__lk); 7697a984708SDavid Chisnall if (this->__exception_ != nullptr) 7707a984708SDavid Chisnall rethrow_exception(this->__exception_); 7717a984708SDavid Chisnall return *__value_; 7727a984708SDavid Chisnall} 7737a984708SDavid Chisnall 77494e3ee44SDavid Chisnalltemplate <class _Rp, class _Alloc> 7750f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc 77694e3ee44SDavid Chisnall : public __assoc_state<_Rp> 7777a984708SDavid Chisnall{ 77894e3ee44SDavid Chisnall typedef __assoc_state<_Rp> base; 7797a984708SDavid Chisnall _Alloc __alloc_; 7807a984708SDavid Chisnall 7817a984708SDavid Chisnall virtual void __on_zero_shared() _NOEXCEPT; 7827a984708SDavid Chisnallpublic: 7837a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 7847a984708SDavid Chisnall explicit __assoc_state_alloc(const _Alloc& __a) 7857a984708SDavid Chisnall : __alloc_(__a) {} 7867a984708SDavid Chisnall}; 7877a984708SDavid Chisnall 78894e3ee44SDavid Chisnalltemplate <class _Rp, class _Alloc> 7897a984708SDavid Chisnallvoid 79094e3ee44SDavid Chisnall__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT 7917a984708SDavid Chisnall{ 7927a984708SDavid Chisnall if (this->__state_ & base::__constructed) 7934f7ab58eSDimitry Andric reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp(); 794854fa44bSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; 795854fa44bSDimitry Andric typedef allocator_traits<_Al> _ATraits; 796d72607e9SDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 797854fa44bSDimitry Andric _Al __a(__alloc_); 7987a984708SDavid Chisnall this->~__assoc_state_alloc(); 799d72607e9SDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 8007a984708SDavid Chisnall} 8017a984708SDavid Chisnall 80294e3ee44SDavid Chisnalltemplate <class _Rp, class _Alloc> 8030f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc> 80494e3ee44SDavid Chisnall : public __assoc_state<_Rp&> 8057a984708SDavid Chisnall{ 80694e3ee44SDavid Chisnall typedef __assoc_state<_Rp&> base; 8077a984708SDavid Chisnall _Alloc __alloc_; 8087a984708SDavid Chisnall 8097a984708SDavid Chisnall virtual void __on_zero_shared() _NOEXCEPT; 8107a984708SDavid Chisnallpublic: 8117a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 8127a984708SDavid Chisnall explicit __assoc_state_alloc(const _Alloc& __a) 8137a984708SDavid Chisnall : __alloc_(__a) {} 8147a984708SDavid Chisnall}; 8157a984708SDavid Chisnall 81694e3ee44SDavid Chisnalltemplate <class _Rp, class _Alloc> 8177a984708SDavid Chisnallvoid 81894e3ee44SDavid Chisnall__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT 8197a984708SDavid Chisnall{ 820854fa44bSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; 821854fa44bSDimitry Andric typedef allocator_traits<_Al> _ATraits; 822d72607e9SDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 823854fa44bSDimitry Andric _Al __a(__alloc_); 8247a984708SDavid Chisnall this->~__assoc_state_alloc(); 825d72607e9SDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 8267a984708SDavid Chisnall} 8277a984708SDavid Chisnall 8287a984708SDavid Chisnalltemplate <class _Alloc> 8290f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc 8307a984708SDavid Chisnall : public __assoc_sub_state 8317a984708SDavid Chisnall{ 8327a984708SDavid Chisnall typedef __assoc_sub_state base; 8337a984708SDavid Chisnall _Alloc __alloc_; 8347a984708SDavid Chisnall 8357a984708SDavid Chisnall virtual void __on_zero_shared() _NOEXCEPT; 8367a984708SDavid Chisnallpublic: 8377a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 8387a984708SDavid Chisnall explicit __assoc_sub_state_alloc(const _Alloc& __a) 8397a984708SDavid Chisnall : __alloc_(__a) {} 8407a984708SDavid Chisnall}; 8417a984708SDavid Chisnall 8427a984708SDavid Chisnalltemplate <class _Alloc> 8437a984708SDavid Chisnallvoid 8447a984708SDavid Chisnall__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT 8457a984708SDavid Chisnall{ 846854fa44bSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al; 847854fa44bSDimitry Andric typedef allocator_traits<_Al> _ATraits; 848d72607e9SDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 849854fa44bSDimitry Andric _Al __a(__alloc_); 8507a984708SDavid Chisnall this->~__assoc_sub_state_alloc(); 851d72607e9SDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 8527a984708SDavid Chisnall} 8537a984708SDavid Chisnall 85494e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 8550f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state 85694e3ee44SDavid Chisnall : public __assoc_state<_Rp> 8577a984708SDavid Chisnall{ 85894e3ee44SDavid Chisnall typedef __assoc_state<_Rp> base; 8597a984708SDavid Chisnall 86094e3ee44SDavid Chisnall _Fp __func_; 8617a984708SDavid Chisnall 8627a984708SDavid Chisnallpublic: 8637a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 8649729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 86594e3ee44SDavid Chisnall explicit __deferred_assoc_state(_Fp&& __f); 8667a984708SDavid Chisnall#endif 8677a984708SDavid Chisnall 8687a984708SDavid Chisnall virtual void __execute(); 8697a984708SDavid Chisnall}; 8707a984708SDavid Chisnall 8717a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 8727a984708SDavid Chisnall 87394e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 8749729cf09SDimitry Andricinline 87594e3ee44SDavid Chisnall__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) 87694e3ee44SDavid Chisnall : __func_(_VSTD::forward<_Fp>(__f)) 8777a984708SDavid Chisnall{ 8787a984708SDavid Chisnall this->__set_deferred(); 8797a984708SDavid Chisnall} 8807a984708SDavid Chisnall 8817a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 8827a984708SDavid Chisnall 88394e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 8847a984708SDavid Chisnallvoid 88594e3ee44SDavid Chisnall__deferred_assoc_state<_Rp, _Fp>::__execute() 8867a984708SDavid Chisnall{ 8877a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 8887a984708SDavid Chisnall try 8897a984708SDavid Chisnall { 8907a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 8917a984708SDavid Chisnall this->set_value(__func_()); 8927a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 8937a984708SDavid Chisnall } 8947a984708SDavid Chisnall catch (...) 8957a984708SDavid Chisnall { 8967a984708SDavid Chisnall this->set_exception(current_exception()); 8977a984708SDavid Chisnall } 8987a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 8997a984708SDavid Chisnall} 9007a984708SDavid Chisnall 90194e3ee44SDavid Chisnalltemplate <class _Fp> 9020f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp> 9037a984708SDavid Chisnall : public __assoc_sub_state 9047a984708SDavid Chisnall{ 9057a984708SDavid Chisnall typedef __assoc_sub_state base; 9067a984708SDavid Chisnall 90794e3ee44SDavid Chisnall _Fp __func_; 9087a984708SDavid Chisnall 9097a984708SDavid Chisnallpublic: 9107a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 9119729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 91294e3ee44SDavid Chisnall explicit __deferred_assoc_state(_Fp&& __f); 9137a984708SDavid Chisnall#endif 9147a984708SDavid Chisnall 9157a984708SDavid Chisnall virtual void __execute(); 9167a984708SDavid Chisnall}; 9177a984708SDavid Chisnall 9187a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 9197a984708SDavid Chisnall 92094e3ee44SDavid Chisnalltemplate <class _Fp> 9219729cf09SDimitry Andricinline 92294e3ee44SDavid Chisnall__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) 92394e3ee44SDavid Chisnall : __func_(_VSTD::forward<_Fp>(__f)) 9247a984708SDavid Chisnall{ 9257a984708SDavid Chisnall this->__set_deferred(); 9267a984708SDavid Chisnall} 9277a984708SDavid Chisnall 9287a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 9297a984708SDavid Chisnall 93094e3ee44SDavid Chisnalltemplate <class _Fp> 9317a984708SDavid Chisnallvoid 93294e3ee44SDavid Chisnall__deferred_assoc_state<void, _Fp>::__execute() 9337a984708SDavid Chisnall{ 9347a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 9357a984708SDavid Chisnall try 9367a984708SDavid Chisnall { 9377a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 9387a984708SDavid Chisnall __func_(); 9397a984708SDavid Chisnall this->set_value(); 9407a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 9417a984708SDavid Chisnall } 9427a984708SDavid Chisnall catch (...) 9437a984708SDavid Chisnall { 9447a984708SDavid Chisnall this->set_exception(current_exception()); 9457a984708SDavid Chisnall } 9467a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 9477a984708SDavid Chisnall} 9487a984708SDavid Chisnall 94994e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 9500f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state 95194e3ee44SDavid Chisnall : public __assoc_state<_Rp> 9527a984708SDavid Chisnall{ 95394e3ee44SDavid Chisnall typedef __assoc_state<_Rp> base; 9547a984708SDavid Chisnall 95594e3ee44SDavid Chisnall _Fp __func_; 9567a984708SDavid Chisnall 9577a984708SDavid Chisnall virtual void __on_zero_shared() _NOEXCEPT; 9587a984708SDavid Chisnallpublic: 9597a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 9609729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 96194e3ee44SDavid Chisnall explicit __async_assoc_state(_Fp&& __f); 9627a984708SDavid Chisnall#endif 9637a984708SDavid Chisnall 9647a984708SDavid Chisnall virtual void __execute(); 9657a984708SDavid Chisnall}; 9667a984708SDavid Chisnall 9677a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 9687a984708SDavid Chisnall 96994e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 9709729cf09SDimitry Andricinline 97194e3ee44SDavid Chisnall__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) 97294e3ee44SDavid Chisnall : __func_(_VSTD::forward<_Fp>(__f)) 9737a984708SDavid Chisnall{ 9747a984708SDavid Chisnall} 9757a984708SDavid Chisnall 9767a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 9777a984708SDavid Chisnall 97894e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 9797a984708SDavid Chisnallvoid 98094e3ee44SDavid Chisnall__async_assoc_state<_Rp, _Fp>::__execute() 9817a984708SDavid Chisnall{ 9827a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 9837a984708SDavid Chisnall try 9847a984708SDavid Chisnall { 9857a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 9867a984708SDavid Chisnall this->set_value(__func_()); 9877a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 9887a984708SDavid Chisnall } 9897a984708SDavid Chisnall catch (...) 9907a984708SDavid Chisnall { 9917a984708SDavid Chisnall this->set_exception(current_exception()); 9927a984708SDavid Chisnall } 9937a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 9947a984708SDavid Chisnall} 9957a984708SDavid Chisnall 99694e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 9977a984708SDavid Chisnallvoid 99894e3ee44SDavid Chisnall__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT 9997a984708SDavid Chisnall{ 10007a984708SDavid Chisnall this->wait(); 10017a984708SDavid Chisnall base::__on_zero_shared(); 10027a984708SDavid Chisnall} 10037a984708SDavid Chisnall 100494e3ee44SDavid Chisnalltemplate <class _Fp> 10050f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp> 10067a984708SDavid Chisnall : public __assoc_sub_state 10077a984708SDavid Chisnall{ 10087a984708SDavid Chisnall typedef __assoc_sub_state base; 10097a984708SDavid Chisnall 101094e3ee44SDavid Chisnall _Fp __func_; 10117a984708SDavid Chisnall 10127a984708SDavid Chisnall virtual void __on_zero_shared() _NOEXCEPT; 10137a984708SDavid Chisnallpublic: 10147a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 10159729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 101694e3ee44SDavid Chisnall explicit __async_assoc_state(_Fp&& __f); 10177a984708SDavid Chisnall#endif 10187a984708SDavid Chisnall 10197a984708SDavid Chisnall virtual void __execute(); 10207a984708SDavid Chisnall}; 10217a984708SDavid Chisnall 10227a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 10237a984708SDavid Chisnall 102494e3ee44SDavid Chisnalltemplate <class _Fp> 10259729cf09SDimitry Andricinline 102694e3ee44SDavid Chisnall__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) 102794e3ee44SDavid Chisnall : __func_(_VSTD::forward<_Fp>(__f)) 10287a984708SDavid Chisnall{ 10297a984708SDavid Chisnall} 10307a984708SDavid Chisnall 10317a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 10327a984708SDavid Chisnall 103394e3ee44SDavid Chisnalltemplate <class _Fp> 10347a984708SDavid Chisnallvoid 103594e3ee44SDavid Chisnall__async_assoc_state<void, _Fp>::__execute() 10367a984708SDavid Chisnall{ 10377a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 10387a984708SDavid Chisnall try 10397a984708SDavid Chisnall { 10407a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 10417a984708SDavid Chisnall __func_(); 10427a984708SDavid Chisnall this->set_value(); 10437a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 10447a984708SDavid Chisnall } 10457a984708SDavid Chisnall catch (...) 10467a984708SDavid Chisnall { 10477a984708SDavid Chisnall this->set_exception(current_exception()); 10487a984708SDavid Chisnall } 10497a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 10507a984708SDavid Chisnall} 10517a984708SDavid Chisnall 105294e3ee44SDavid Chisnalltemplate <class _Fp> 10537a984708SDavid Chisnallvoid 105494e3ee44SDavid Chisnall__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT 10557a984708SDavid Chisnall{ 10567a984708SDavid Chisnall this->wait(); 10577a984708SDavid Chisnall base::__on_zero_shared(); 10587a984708SDavid Chisnall} 10597a984708SDavid Chisnall 1060aed8d94eSDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS promise; 1061aed8d94eSDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future; 10627a984708SDavid Chisnall 10637a984708SDavid Chisnall// future 10647a984708SDavid Chisnall 1065aed8d94eSDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS future; 10667a984708SDavid Chisnall 106794e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 106894e3ee44SDavid Chisnallfuture<_Rp> 10697a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 107094e3ee44SDavid Chisnall__make_deferred_assoc_state(_Fp&& __f); 10717a984708SDavid Chisnall#else 107294e3ee44SDavid Chisnall__make_deferred_assoc_state(_Fp __f); 10737a984708SDavid Chisnall#endif 10747a984708SDavid Chisnall 107594e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 107694e3ee44SDavid Chisnallfuture<_Rp> 10777a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 107894e3ee44SDavid Chisnall__make_async_assoc_state(_Fp&& __f); 10797a984708SDavid Chisnall#else 108094e3ee44SDavid Chisnall__make_async_assoc_state(_Fp __f); 10817a984708SDavid Chisnall#endif 10827a984708SDavid Chisnall 108394e3ee44SDavid Chisnalltemplate <class _Rp> 10840f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future 10857a984708SDavid Chisnall{ 108694e3ee44SDavid Chisnall __assoc_state<_Rp>* __state_; 10877a984708SDavid Chisnall 108894e3ee44SDavid Chisnall explicit future(__assoc_state<_Rp>* __state); 10897a984708SDavid Chisnall 10907a984708SDavid Chisnall template <class> friend class promise; 10917a984708SDavid Chisnall template <class> friend class shared_future; 10927a984708SDavid Chisnall 10937a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 109494e3ee44SDavid Chisnall template <class _R1, class _Fp> 109594e3ee44SDavid Chisnall friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 109694e3ee44SDavid Chisnall template <class _R1, class _Fp> 109794e3ee44SDavid Chisnall friend future<_R1> __make_async_assoc_state(_Fp&& __f); 10987a984708SDavid Chisnall#else 109994e3ee44SDavid Chisnall template <class _R1, class _Fp> 110094e3ee44SDavid Chisnall friend future<_R1> __make_deferred_assoc_state(_Fp __f); 110194e3ee44SDavid Chisnall template <class _R1, class _Fp> 110294e3ee44SDavid Chisnall friend future<_R1> __make_async_assoc_state(_Fp __f); 11037a984708SDavid Chisnall#endif 11047a984708SDavid Chisnall 11057a984708SDavid Chisnallpublic: 11067a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1107936e9439SDimitry Andric future() _NOEXCEPT : __state_(nullptr) {} 11087a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 11097a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1110936e9439SDimitry Andric future(future&& __rhs) _NOEXCEPT 11117a984708SDavid Chisnall : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 11127a984708SDavid Chisnall future(const future&) = delete; 11137a984708SDavid Chisnall future& operator=(const future&) = delete; 11147a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1115936e9439SDimitry Andric future& operator=(future&& __rhs) _NOEXCEPT 11167a984708SDavid Chisnall { 11177a984708SDavid Chisnall future(std::move(__rhs)).swap(*this); 11187a984708SDavid Chisnall return *this; 11197a984708SDavid Chisnall } 11207a984708SDavid Chisnall#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 11217a984708SDavid Chisnallprivate: 11227a984708SDavid Chisnall future(const future&); 11237a984708SDavid Chisnall future& operator=(const future&); 11247a984708SDavid Chisnallpublic: 11257a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 11267a984708SDavid Chisnall ~future(); 11279729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1128540d2a8bSDimitry Andric shared_future<_Rp> share() _NOEXCEPT; 11297a984708SDavid Chisnall 11307a984708SDavid Chisnall // retrieving the value 113194e3ee44SDavid Chisnall _Rp get(); 11327a984708SDavid Chisnall 11337a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1134936e9439SDimitry Andric void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 11357a984708SDavid Chisnall 11367a984708SDavid Chisnall // functions to check state 11377a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1138936e9439SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 11397a984708SDavid Chisnall 11407a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 11417a984708SDavid Chisnall void wait() const {__state_->wait();} 11427a984708SDavid Chisnall template <class _Rep, class _Period> 11437a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 11447a984708SDavid Chisnall future_status 11457a984708SDavid Chisnall wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 11467a984708SDavid Chisnall {return __state_->wait_for(__rel_time);} 11477a984708SDavid Chisnall template <class _Clock, class _Duration> 11487a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 11497a984708SDavid Chisnall future_status 11507a984708SDavid Chisnall wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 11517a984708SDavid Chisnall {return __state_->wait_until(__abs_time);} 11527a984708SDavid Chisnall}; 11537a984708SDavid Chisnall 115494e3ee44SDavid Chisnalltemplate <class _Rp> 115594e3ee44SDavid Chisnallfuture<_Rp>::future(__assoc_state<_Rp>* __state) 11567a984708SDavid Chisnall : __state_(__state) 11577a984708SDavid Chisnall{ 1158*b5893f02SDimitry Andric __state_->__attach_future(); 11597a984708SDavid Chisnall} 11607a984708SDavid Chisnall 11617a984708SDavid Chisnallstruct __release_shared_count 11627a984708SDavid Chisnall{ 11637a984708SDavid Chisnall void operator()(__shared_count* p) {p->__release_shared();} 11647a984708SDavid Chisnall}; 11657a984708SDavid Chisnall 116694e3ee44SDavid Chisnalltemplate <class _Rp> 116794e3ee44SDavid Chisnallfuture<_Rp>::~future() 11687a984708SDavid Chisnall{ 11697a984708SDavid Chisnall if (__state_) 11707a984708SDavid Chisnall __state_->__release_shared(); 11717a984708SDavid Chisnall} 11727a984708SDavid Chisnall 117394e3ee44SDavid Chisnalltemplate <class _Rp> 117494e3ee44SDavid Chisnall_Rp 117594e3ee44SDavid Chisnallfuture<_Rp>::get() 11767a984708SDavid Chisnall{ 11777a984708SDavid Chisnall unique_ptr<__shared_count, __release_shared_count> __(__state_); 117894e3ee44SDavid Chisnall __assoc_state<_Rp>* __s = __state_; 11797a984708SDavid Chisnall __state_ = nullptr; 11807a984708SDavid Chisnall return __s->move(); 11817a984708SDavid Chisnall} 11827a984708SDavid Chisnall 118394e3ee44SDavid Chisnalltemplate <class _Rp> 11840f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&> 11857a984708SDavid Chisnall{ 118694e3ee44SDavid Chisnall __assoc_state<_Rp&>* __state_; 11877a984708SDavid Chisnall 118894e3ee44SDavid Chisnall explicit future(__assoc_state<_Rp&>* __state); 11897a984708SDavid Chisnall 11907a984708SDavid Chisnall template <class> friend class promise; 11917a984708SDavid Chisnall template <class> friend class shared_future; 11927a984708SDavid Chisnall 11937a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 119494e3ee44SDavid Chisnall template <class _R1, class _Fp> 119594e3ee44SDavid Chisnall friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 119694e3ee44SDavid Chisnall template <class _R1, class _Fp> 119794e3ee44SDavid Chisnall friend future<_R1> __make_async_assoc_state(_Fp&& __f); 11987a984708SDavid Chisnall#else 119994e3ee44SDavid Chisnall template <class _R1, class _Fp> 120094e3ee44SDavid Chisnall friend future<_R1> __make_deferred_assoc_state(_Fp __f); 120194e3ee44SDavid Chisnall template <class _R1, class _Fp> 120294e3ee44SDavid Chisnall friend future<_R1> __make_async_assoc_state(_Fp __f); 12037a984708SDavid Chisnall#endif 12047a984708SDavid Chisnall 12057a984708SDavid Chisnallpublic: 12067a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1207936e9439SDimitry Andric future() _NOEXCEPT : __state_(nullptr) {} 12087a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 12097a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1210936e9439SDimitry Andric future(future&& __rhs) _NOEXCEPT 12117a984708SDavid Chisnall : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 12127a984708SDavid Chisnall future(const future&) = delete; 12137a984708SDavid Chisnall future& operator=(const future&) = delete; 12147a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1215936e9439SDimitry Andric future& operator=(future&& __rhs) _NOEXCEPT 12167a984708SDavid Chisnall { 12177a984708SDavid Chisnall future(std::move(__rhs)).swap(*this); 12187a984708SDavid Chisnall return *this; 12197a984708SDavid Chisnall } 12207a984708SDavid Chisnall#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 12217a984708SDavid Chisnallprivate: 12227a984708SDavid Chisnall future(const future&); 12237a984708SDavid Chisnall future& operator=(const future&); 12247a984708SDavid Chisnallpublic: 12257a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 12267a984708SDavid Chisnall ~future(); 12279729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1228540d2a8bSDimitry Andric shared_future<_Rp&> share() _NOEXCEPT; 12297a984708SDavid Chisnall 12307a984708SDavid Chisnall // retrieving the value 123194e3ee44SDavid Chisnall _Rp& get(); 12327a984708SDavid Chisnall 12337a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1234936e9439SDimitry Andric void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 12357a984708SDavid Chisnall 12367a984708SDavid Chisnall // functions to check state 12377a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1238936e9439SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 12397a984708SDavid Chisnall 12407a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 12417a984708SDavid Chisnall void wait() const {__state_->wait();} 12427a984708SDavid Chisnall template <class _Rep, class _Period> 12437a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 12447a984708SDavid Chisnall future_status 12457a984708SDavid Chisnall wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 12467a984708SDavid Chisnall {return __state_->wait_for(__rel_time);} 12477a984708SDavid Chisnall template <class _Clock, class _Duration> 12487a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 12497a984708SDavid Chisnall future_status 12507a984708SDavid Chisnall wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 12517a984708SDavid Chisnall {return __state_->wait_until(__abs_time);} 12527a984708SDavid Chisnall}; 12537a984708SDavid Chisnall 125494e3ee44SDavid Chisnalltemplate <class _Rp> 125594e3ee44SDavid Chisnallfuture<_Rp&>::future(__assoc_state<_Rp&>* __state) 12567a984708SDavid Chisnall : __state_(__state) 12577a984708SDavid Chisnall{ 1258*b5893f02SDimitry Andric __state_->__attach_future(); 12597a984708SDavid Chisnall} 12607a984708SDavid Chisnall 126194e3ee44SDavid Chisnalltemplate <class _Rp> 126294e3ee44SDavid Chisnallfuture<_Rp&>::~future() 12637a984708SDavid Chisnall{ 12647a984708SDavid Chisnall if (__state_) 12657a984708SDavid Chisnall __state_->__release_shared(); 12667a984708SDavid Chisnall} 12677a984708SDavid Chisnall 126894e3ee44SDavid Chisnalltemplate <class _Rp> 126994e3ee44SDavid Chisnall_Rp& 127094e3ee44SDavid Chisnallfuture<_Rp&>::get() 12717a984708SDavid Chisnall{ 12727a984708SDavid Chisnall unique_ptr<__shared_count, __release_shared_count> __(__state_); 127394e3ee44SDavid Chisnall __assoc_state<_Rp&>* __s = __state_; 12747a984708SDavid Chisnall __state_ = nullptr; 12757a984708SDavid Chisnall return __s->copy(); 12767a984708SDavid Chisnall} 12777a984708SDavid Chisnall 12787a984708SDavid Chisnalltemplate <> 12790f5676f4SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void> 12807a984708SDavid Chisnall{ 12817a984708SDavid Chisnall __assoc_sub_state* __state_; 12827a984708SDavid Chisnall 12837a984708SDavid Chisnall explicit future(__assoc_sub_state* __state); 12847a984708SDavid Chisnall 12857a984708SDavid Chisnall template <class> friend class promise; 12867a984708SDavid Chisnall template <class> friend class shared_future; 12877a984708SDavid Chisnall 12887a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 128994e3ee44SDavid Chisnall template <class _R1, class _Fp> 129094e3ee44SDavid Chisnall friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 129194e3ee44SDavid Chisnall template <class _R1, class _Fp> 129294e3ee44SDavid Chisnall friend future<_R1> __make_async_assoc_state(_Fp&& __f); 12937a984708SDavid Chisnall#else 129494e3ee44SDavid Chisnall template <class _R1, class _Fp> 129594e3ee44SDavid Chisnall friend future<_R1> __make_deferred_assoc_state(_Fp __f); 129694e3ee44SDavid Chisnall template <class _R1, class _Fp> 129794e3ee44SDavid Chisnall friend future<_R1> __make_async_assoc_state(_Fp __f); 12987a984708SDavid Chisnall#endif 12997a984708SDavid Chisnall 13007a984708SDavid Chisnallpublic: 13017a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1302936e9439SDimitry Andric future() _NOEXCEPT : __state_(nullptr) {} 13037a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 13047a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1305936e9439SDimitry Andric future(future&& __rhs) _NOEXCEPT 13067a984708SDavid Chisnall : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 13077a984708SDavid Chisnall future(const future&) = delete; 13087a984708SDavid Chisnall future& operator=(const future&) = delete; 13097a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1310936e9439SDimitry Andric future& operator=(future&& __rhs) _NOEXCEPT 13117a984708SDavid Chisnall { 13127a984708SDavid Chisnall future(std::move(__rhs)).swap(*this); 13137a984708SDavid Chisnall return *this; 13147a984708SDavid Chisnall } 13157a984708SDavid Chisnall#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 13167a984708SDavid Chisnallprivate: 13177a984708SDavid Chisnall future(const future&); 13187a984708SDavid Chisnall future& operator=(const future&); 13197a984708SDavid Chisnallpublic: 13207a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 13217a984708SDavid Chisnall ~future(); 13229729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1323540d2a8bSDimitry Andric shared_future<void> share() _NOEXCEPT; 13247a984708SDavid Chisnall 13257a984708SDavid Chisnall // retrieving the value 13267a984708SDavid Chisnall void get(); 13277a984708SDavid Chisnall 13287a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1329936e9439SDimitry Andric void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 13307a984708SDavid Chisnall 13317a984708SDavid Chisnall // functions to check state 13327a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1333936e9439SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 13347a984708SDavid Chisnall 13357a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 13367a984708SDavid Chisnall void wait() const {__state_->wait();} 13377a984708SDavid Chisnall template <class _Rep, class _Period> 13387a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 13397a984708SDavid Chisnall future_status 13407a984708SDavid Chisnall wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 13417a984708SDavid Chisnall {return __state_->wait_for(__rel_time);} 13427a984708SDavid Chisnall template <class _Clock, class _Duration> 13437a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 13447a984708SDavid Chisnall future_status 13457a984708SDavid Chisnall wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 13467a984708SDavid Chisnall {return __state_->wait_until(__abs_time);} 13477a984708SDavid Chisnall}; 13487a984708SDavid Chisnall 134994e3ee44SDavid Chisnalltemplate <class _Rp> 13507a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 13517a984708SDavid Chisnallvoid 1352936e9439SDimitry Andricswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT 13537a984708SDavid Chisnall{ 13547a984708SDavid Chisnall __x.swap(__y); 13557a984708SDavid Chisnall} 13567a984708SDavid Chisnall 13577a984708SDavid Chisnall// promise<R> 13587a984708SDavid Chisnall 13597a984708SDavid Chisnalltemplate <class _Callable> class packaged_task; 13607a984708SDavid Chisnall 136194e3ee44SDavid Chisnalltemplate <class _Rp> 13620f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise 13637a984708SDavid Chisnall{ 136494e3ee44SDavid Chisnall __assoc_state<_Rp>* __state_; 13657a984708SDavid Chisnall 13667a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1367936e9439SDimitry Andric explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 13687a984708SDavid Chisnall 13697a984708SDavid Chisnall template <class> friend class packaged_task; 13707a984708SDavid Chisnallpublic: 13717a984708SDavid Chisnall promise(); 13727a984708SDavid Chisnall template <class _Alloc> 13737a984708SDavid Chisnall promise(allocator_arg_t, const _Alloc& __a); 13747a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 13757a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1376936e9439SDimitry Andric promise(promise&& __rhs) _NOEXCEPT 13777a984708SDavid Chisnall : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 13787a984708SDavid Chisnall promise(const promise& __rhs) = delete; 13797a984708SDavid Chisnall#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 13807a984708SDavid Chisnallprivate: 13817a984708SDavid Chisnall promise(const promise& __rhs); 13827a984708SDavid Chisnallpublic: 13837a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 13847a984708SDavid Chisnall ~promise(); 13857a984708SDavid Chisnall 13867a984708SDavid Chisnall // assignment 13877a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 13887a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1389936e9439SDimitry Andric promise& operator=(promise&& __rhs) _NOEXCEPT 13907a984708SDavid Chisnall { 13917a984708SDavid Chisnall promise(std::move(__rhs)).swap(*this); 13927a984708SDavid Chisnall return *this; 13937a984708SDavid Chisnall } 13947a984708SDavid Chisnall promise& operator=(const promise& __rhs) = delete; 13957a984708SDavid Chisnall#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 13967a984708SDavid Chisnallprivate: 13977a984708SDavid Chisnall promise& operator=(const promise& __rhs); 13987a984708SDavid Chisnallpublic: 13997a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 14007a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1401936e9439SDimitry Andric void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 14027a984708SDavid Chisnall 14037a984708SDavid Chisnall // retrieving the result 140494e3ee44SDavid Chisnall future<_Rp> get_future(); 14057a984708SDavid Chisnall 14067a984708SDavid Chisnall // setting the result 140794e3ee44SDavid Chisnall void set_value(const _Rp& __r); 14087a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 140994e3ee44SDavid Chisnall void set_value(_Rp&& __r); 14107a984708SDavid Chisnall#endif 14117a984708SDavid Chisnall void set_exception(exception_ptr __p); 14127a984708SDavid Chisnall 14137a984708SDavid Chisnall // setting the result with deferred notification 141494e3ee44SDavid Chisnall void set_value_at_thread_exit(const _Rp& __r); 14157a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 141694e3ee44SDavid Chisnall void set_value_at_thread_exit(_Rp&& __r); 14177a984708SDavid Chisnall#endif 14187a984708SDavid Chisnall void set_exception_at_thread_exit(exception_ptr __p); 14197a984708SDavid Chisnall}; 14207a984708SDavid Chisnall 142194e3ee44SDavid Chisnalltemplate <class _Rp> 142294e3ee44SDavid Chisnallpromise<_Rp>::promise() 142394e3ee44SDavid Chisnall : __state_(new __assoc_state<_Rp>) 14247a984708SDavid Chisnall{ 14257a984708SDavid Chisnall} 14267a984708SDavid Chisnall 142794e3ee44SDavid Chisnalltemplate <class _Rp> 14287a984708SDavid Chisnalltemplate <class _Alloc> 142994e3ee44SDavid Chisnallpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) 14307a984708SDavid Chisnall{ 1431d72607e9SDimitry Andric typedef __assoc_state_alloc<_Rp, _Alloc> _State; 1432d72607e9SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; 14337a984708SDavid Chisnall typedef __allocator_destructor<_A2> _D2; 14347a984708SDavid Chisnall _A2 __a(__a0); 1435d72607e9SDimitry Andric unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1436d72607e9SDimitry Andric ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0); 1437d72607e9SDimitry Andric __state_ = _VSTD::addressof(*__hold.release()); 14387a984708SDavid Chisnall} 14397a984708SDavid Chisnall 144094e3ee44SDavid Chisnalltemplate <class _Rp> 144194e3ee44SDavid Chisnallpromise<_Rp>::~promise() 14427a984708SDavid Chisnall{ 14437a984708SDavid Chisnall if (__state_) 14447a984708SDavid Chisnall { 14457a984708SDavid Chisnall if (!__state_->__has_value() && __state_->use_count() > 1) 14467a984708SDavid Chisnall __state_->set_exception(make_exception_ptr( 14477a984708SDavid Chisnall future_error(make_error_code(future_errc::broken_promise)) 14487a984708SDavid Chisnall )); 14497a984708SDavid Chisnall __state_->__release_shared(); 14507a984708SDavid Chisnall } 14517a984708SDavid Chisnall} 14527a984708SDavid Chisnall 145394e3ee44SDavid Chisnalltemplate <class _Rp> 145494e3ee44SDavid Chisnallfuture<_Rp> 145594e3ee44SDavid Chisnallpromise<_Rp>::get_future() 14567a984708SDavid Chisnall{ 14577a984708SDavid Chisnall if (__state_ == nullptr) 14589729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 145994e3ee44SDavid Chisnall return future<_Rp>(__state_); 14607a984708SDavid Chisnall} 14617a984708SDavid Chisnall 146294e3ee44SDavid Chisnalltemplate <class _Rp> 14637a984708SDavid Chisnallvoid 146494e3ee44SDavid Chisnallpromise<_Rp>::set_value(const _Rp& __r) 14657a984708SDavid Chisnall{ 14667a984708SDavid Chisnall if (__state_ == nullptr) 14679729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 14687a984708SDavid Chisnall __state_->set_value(__r); 14697a984708SDavid Chisnall} 14707a984708SDavid Chisnall 14717a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 14727a984708SDavid Chisnall 147394e3ee44SDavid Chisnalltemplate <class _Rp> 14747a984708SDavid Chisnallvoid 147594e3ee44SDavid Chisnallpromise<_Rp>::set_value(_Rp&& __r) 14767a984708SDavid Chisnall{ 14777a984708SDavid Chisnall if (__state_ == nullptr) 14789729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 14797a984708SDavid Chisnall __state_->set_value(_VSTD::move(__r)); 14807a984708SDavid Chisnall} 14817a984708SDavid Chisnall 14827a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 14837a984708SDavid Chisnall 148494e3ee44SDavid Chisnalltemplate <class _Rp> 14857a984708SDavid Chisnallvoid 148694e3ee44SDavid Chisnallpromise<_Rp>::set_exception(exception_ptr __p) 14877a984708SDavid Chisnall{ 14887c82a1ecSDimitry Andric _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" ); 14897a984708SDavid Chisnall if (__state_ == nullptr) 14909729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 14917a984708SDavid Chisnall __state_->set_exception(__p); 14927a984708SDavid Chisnall} 14937a984708SDavid Chisnall 149494e3ee44SDavid Chisnalltemplate <class _Rp> 14957a984708SDavid Chisnallvoid 149694e3ee44SDavid Chisnallpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r) 14977a984708SDavid Chisnall{ 14987a984708SDavid Chisnall if (__state_ == nullptr) 14999729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 15007a984708SDavid Chisnall __state_->set_value_at_thread_exit(__r); 15017a984708SDavid Chisnall} 15027a984708SDavid Chisnall 15037a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 15047a984708SDavid Chisnall 150594e3ee44SDavid Chisnalltemplate <class _Rp> 15067a984708SDavid Chisnallvoid 150794e3ee44SDavid Chisnallpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r) 15087a984708SDavid Chisnall{ 15097a984708SDavid Chisnall if (__state_ == nullptr) 15109729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 15117a984708SDavid Chisnall __state_->set_value_at_thread_exit(_VSTD::move(__r)); 15127a984708SDavid Chisnall} 15137a984708SDavid Chisnall 15147a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 15157a984708SDavid Chisnall 151694e3ee44SDavid Chisnalltemplate <class _Rp> 15177a984708SDavid Chisnallvoid 151894e3ee44SDavid Chisnallpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) 15197a984708SDavid Chisnall{ 15207c82a1ecSDimitry Andric _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); 15217a984708SDavid Chisnall if (__state_ == nullptr) 15229729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 15237a984708SDavid Chisnall __state_->set_exception_at_thread_exit(__p); 15247a984708SDavid Chisnall} 15257a984708SDavid Chisnall 15267a984708SDavid Chisnall// promise<R&> 15277a984708SDavid Chisnall 152894e3ee44SDavid Chisnalltemplate <class _Rp> 15290f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&> 15307a984708SDavid Chisnall{ 153194e3ee44SDavid Chisnall __assoc_state<_Rp&>* __state_; 15327a984708SDavid Chisnall 15337a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1534936e9439SDimitry Andric explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 15357a984708SDavid Chisnall 15367a984708SDavid Chisnall template <class> friend class packaged_task; 15377a984708SDavid Chisnall 15387a984708SDavid Chisnallpublic: 15397a984708SDavid Chisnall promise(); 15407a984708SDavid Chisnall template <class _Allocator> 15417a984708SDavid Chisnall promise(allocator_arg_t, const _Allocator& __a); 15427a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 15437a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1544936e9439SDimitry Andric promise(promise&& __rhs) _NOEXCEPT 15457a984708SDavid Chisnall : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 15467a984708SDavid Chisnall promise(const promise& __rhs) = delete; 15477a984708SDavid Chisnall#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 15487a984708SDavid Chisnallprivate: 15497a984708SDavid Chisnall promise(const promise& __rhs); 15507a984708SDavid Chisnallpublic: 15517a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 15527a984708SDavid Chisnall ~promise(); 15537a984708SDavid Chisnall 15547a984708SDavid Chisnall // assignment 15557a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 15567a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1557936e9439SDimitry Andric promise& operator=(promise&& __rhs) _NOEXCEPT 15587a984708SDavid Chisnall { 15597a984708SDavid Chisnall promise(std::move(__rhs)).swap(*this); 15607a984708SDavid Chisnall return *this; 15617a984708SDavid Chisnall } 15627a984708SDavid Chisnall promise& operator=(const promise& __rhs) = delete; 15637a984708SDavid Chisnall#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 15647a984708SDavid Chisnallprivate: 15657a984708SDavid Chisnall promise& operator=(const promise& __rhs); 15667a984708SDavid Chisnallpublic: 15677a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 15687a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1569936e9439SDimitry Andric void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 15707a984708SDavid Chisnall 15717a984708SDavid Chisnall // retrieving the result 157294e3ee44SDavid Chisnall future<_Rp&> get_future(); 15737a984708SDavid Chisnall 15747a984708SDavid Chisnall // setting the result 157594e3ee44SDavid Chisnall void set_value(_Rp& __r); 15767a984708SDavid Chisnall void set_exception(exception_ptr __p); 15777a984708SDavid Chisnall 15787a984708SDavid Chisnall // setting the result with deferred notification 157994e3ee44SDavid Chisnall void set_value_at_thread_exit(_Rp&); 15807a984708SDavid Chisnall void set_exception_at_thread_exit(exception_ptr __p); 15817a984708SDavid Chisnall}; 15827a984708SDavid Chisnall 158394e3ee44SDavid Chisnalltemplate <class _Rp> 158494e3ee44SDavid Chisnallpromise<_Rp&>::promise() 158594e3ee44SDavid Chisnall : __state_(new __assoc_state<_Rp&>) 15867a984708SDavid Chisnall{ 15877a984708SDavid Chisnall} 15887a984708SDavid Chisnall 158994e3ee44SDavid Chisnalltemplate <class _Rp> 15907a984708SDavid Chisnalltemplate <class _Alloc> 159194e3ee44SDavid Chisnallpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) 15927a984708SDavid Chisnall{ 1593d72607e9SDimitry Andric typedef __assoc_state_alloc<_Rp&, _Alloc> _State; 1594d72607e9SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; 15957a984708SDavid Chisnall typedef __allocator_destructor<_A2> _D2; 15967a984708SDavid Chisnall _A2 __a(__a0); 1597d72607e9SDimitry Andric unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1598d72607e9SDimitry Andric ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0); 1599d72607e9SDimitry Andric __state_ = _VSTD::addressof(*__hold.release()); 16007a984708SDavid Chisnall} 16017a984708SDavid Chisnall 160294e3ee44SDavid Chisnalltemplate <class _Rp> 160394e3ee44SDavid Chisnallpromise<_Rp&>::~promise() 16047a984708SDavid Chisnall{ 16057a984708SDavid Chisnall if (__state_) 16067a984708SDavid Chisnall { 16077a984708SDavid Chisnall if (!__state_->__has_value() && __state_->use_count() > 1) 16087a984708SDavid Chisnall __state_->set_exception(make_exception_ptr( 16097a984708SDavid Chisnall future_error(make_error_code(future_errc::broken_promise)) 16107a984708SDavid Chisnall )); 16117a984708SDavid Chisnall __state_->__release_shared(); 16127a984708SDavid Chisnall } 16137a984708SDavid Chisnall} 16147a984708SDavid Chisnall 161594e3ee44SDavid Chisnalltemplate <class _Rp> 161694e3ee44SDavid Chisnallfuture<_Rp&> 161794e3ee44SDavid Chisnallpromise<_Rp&>::get_future() 16187a984708SDavid Chisnall{ 16197a984708SDavid Chisnall if (__state_ == nullptr) 16209729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 162194e3ee44SDavid Chisnall return future<_Rp&>(__state_); 16227a984708SDavid Chisnall} 16237a984708SDavid Chisnall 162494e3ee44SDavid Chisnalltemplate <class _Rp> 16257a984708SDavid Chisnallvoid 162694e3ee44SDavid Chisnallpromise<_Rp&>::set_value(_Rp& __r) 16277a984708SDavid Chisnall{ 16287a984708SDavid Chisnall if (__state_ == nullptr) 16299729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 16307a984708SDavid Chisnall __state_->set_value(__r); 16317a984708SDavid Chisnall} 16327a984708SDavid Chisnall 163394e3ee44SDavid Chisnalltemplate <class _Rp> 16347a984708SDavid Chisnallvoid 163594e3ee44SDavid Chisnallpromise<_Rp&>::set_exception(exception_ptr __p) 16367a984708SDavid Chisnall{ 16377c82a1ecSDimitry Andric _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" ); 16387a984708SDavid Chisnall if (__state_ == nullptr) 16399729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 16407a984708SDavid Chisnall __state_->set_exception(__p); 16417a984708SDavid Chisnall} 16427a984708SDavid Chisnall 164394e3ee44SDavid Chisnalltemplate <class _Rp> 16447a984708SDavid Chisnallvoid 164594e3ee44SDavid Chisnallpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r) 16467a984708SDavid Chisnall{ 16477a984708SDavid Chisnall if (__state_ == nullptr) 16489729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 16497a984708SDavid Chisnall __state_->set_value_at_thread_exit(__r); 16507a984708SDavid Chisnall} 16517a984708SDavid Chisnall 165294e3ee44SDavid Chisnalltemplate <class _Rp> 16537a984708SDavid Chisnallvoid 165494e3ee44SDavid Chisnallpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) 16557a984708SDavid Chisnall{ 16567c82a1ecSDimitry Andric _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); 16577a984708SDavid Chisnall if (__state_ == nullptr) 16589729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 16597a984708SDavid Chisnall __state_->set_exception_at_thread_exit(__p); 16607a984708SDavid Chisnall} 16617a984708SDavid Chisnall 16627a984708SDavid Chisnall// promise<void> 16637a984708SDavid Chisnall 16647a984708SDavid Chisnalltemplate <> 16650f5676f4SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void> 16667a984708SDavid Chisnall{ 16677a984708SDavid Chisnall __assoc_sub_state* __state_; 16687a984708SDavid Chisnall 16697a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1670936e9439SDimitry Andric explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 16717a984708SDavid Chisnall 16727a984708SDavid Chisnall template <class> friend class packaged_task; 16737a984708SDavid Chisnall 16747a984708SDavid Chisnallpublic: 16757a984708SDavid Chisnall promise(); 16767a984708SDavid Chisnall template <class _Allocator> 1677540d2a8bSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 16787a984708SDavid Chisnall promise(allocator_arg_t, const _Allocator& __a); 16797a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 16807a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1681936e9439SDimitry Andric promise(promise&& __rhs) _NOEXCEPT 16827a984708SDavid Chisnall : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 16837a984708SDavid Chisnall promise(const promise& __rhs) = delete; 16847a984708SDavid Chisnall#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 16857a984708SDavid Chisnallprivate: 16867a984708SDavid Chisnall promise(const promise& __rhs); 16877a984708SDavid Chisnallpublic: 16887a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 16897a984708SDavid Chisnall ~promise(); 16907a984708SDavid Chisnall 16917a984708SDavid Chisnall // assignment 16927a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 16937a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1694936e9439SDimitry Andric promise& operator=(promise&& __rhs) _NOEXCEPT 16957a984708SDavid Chisnall { 16967a984708SDavid Chisnall promise(std::move(__rhs)).swap(*this); 16977a984708SDavid Chisnall return *this; 16987a984708SDavid Chisnall } 16997a984708SDavid Chisnall promise& operator=(const promise& __rhs) = delete; 17007a984708SDavid Chisnall#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 17017a984708SDavid Chisnallprivate: 17027a984708SDavid Chisnall promise& operator=(const promise& __rhs); 17037a984708SDavid Chisnallpublic: 17047a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 17057a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1706936e9439SDimitry Andric void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 17077a984708SDavid Chisnall 17087a984708SDavid Chisnall // retrieving the result 17097a984708SDavid Chisnall future<void> get_future(); 17107a984708SDavid Chisnall 17117a984708SDavid Chisnall // setting the result 17127a984708SDavid Chisnall void set_value(); 17137a984708SDavid Chisnall void set_exception(exception_ptr __p); 17147a984708SDavid Chisnall 17157a984708SDavid Chisnall // setting the result with deferred notification 17167a984708SDavid Chisnall void set_value_at_thread_exit(); 17177a984708SDavid Chisnall void set_exception_at_thread_exit(exception_ptr __p); 17187a984708SDavid Chisnall}; 17197a984708SDavid Chisnall 17207a984708SDavid Chisnalltemplate <class _Alloc> 17217a984708SDavid Chisnallpromise<void>::promise(allocator_arg_t, const _Alloc& __a0) 17227a984708SDavid Chisnall{ 1723d72607e9SDimitry Andric typedef __assoc_sub_state_alloc<_Alloc> _State; 1724d72607e9SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; 17257a984708SDavid Chisnall typedef __allocator_destructor<_A2> _D2; 17267a984708SDavid Chisnall _A2 __a(__a0); 1727d72607e9SDimitry Andric unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1728d72607e9SDimitry Andric ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0); 1729d72607e9SDimitry Andric __state_ = _VSTD::addressof(*__hold.release()); 17307a984708SDavid Chisnall} 17317a984708SDavid Chisnall 173294e3ee44SDavid Chisnalltemplate <class _Rp> 17337a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 17347a984708SDavid Chisnallvoid 1735936e9439SDimitry Andricswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT 17367a984708SDavid Chisnall{ 17377a984708SDavid Chisnall __x.swap(__y); 17387a984708SDavid Chisnall} 17397a984708SDavid Chisnall 174094e3ee44SDavid Chisnalltemplate <class _Rp, class _Alloc> 1741aed8d94eSDimitry Andric struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc> 17427a984708SDavid Chisnall : public true_type {}; 17437a984708SDavid Chisnall 17447a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS 17457a984708SDavid Chisnall 17467a984708SDavid Chisnall// packaged_task 17477a984708SDavid Chisnall 17487a984708SDavid Chisnalltemplate<class _Fp> class __packaged_task_base; 17497a984708SDavid Chisnall 175094e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 17510f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)> 17527a984708SDavid Chisnall{ 17537a984708SDavid Chisnall __packaged_task_base(const __packaged_task_base&); 17547a984708SDavid Chisnall __packaged_task_base& operator=(const __packaged_task_base&); 17557a984708SDavid Chisnallpublic: 17567a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 17577a984708SDavid Chisnall __packaged_task_base() {} 17587a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 17597a984708SDavid Chisnall virtual ~__packaged_task_base() {} 1760936e9439SDimitry Andric virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0; 17617a984708SDavid Chisnall virtual void destroy() = 0; 17627a984708SDavid Chisnall virtual void destroy_deallocate() = 0; 176394e3ee44SDavid Chisnall virtual _Rp operator()(_ArgTypes&& ...) = 0; 17647a984708SDavid Chisnall}; 17657a984708SDavid Chisnall 17667a984708SDavid Chisnalltemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func; 17677a984708SDavid Chisnall 176894e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 17690f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> 177094e3ee44SDavid Chisnall : public __packaged_task_base<_Rp(_ArgTypes...)> 17717a984708SDavid Chisnall{ 177294e3ee44SDavid Chisnall __compressed_pair<_Fp, _Alloc> __f_; 17737a984708SDavid Chisnallpublic: 17747a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 177594e3ee44SDavid Chisnall explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {} 17767a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 177794e3ee44SDavid Chisnall explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {} 17787a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 177994e3ee44SDavid Chisnall __packaged_task_func(const _Fp& __f, const _Alloc& __a) 17807a984708SDavid Chisnall : __f_(__f, __a) {} 17817a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 178294e3ee44SDavid Chisnall __packaged_task_func(_Fp&& __f, const _Alloc& __a) 17837a984708SDavid Chisnall : __f_(_VSTD::move(__f), __a) {} 1784936e9439SDimitry Andric virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; 17857a984708SDavid Chisnall virtual void destroy(); 17867a984708SDavid Chisnall virtual void destroy_deallocate(); 178794e3ee44SDavid Chisnall virtual _Rp operator()(_ArgTypes&& ... __args); 17887a984708SDavid Chisnall}; 17897a984708SDavid Chisnall 179094e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 17917a984708SDavid Chisnallvoid 179294e3ee44SDavid Chisnall__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to( 1793936e9439SDimitry Andric __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT 17947a984708SDavid Chisnall{ 17957a984708SDavid Chisnall ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second())); 17967a984708SDavid Chisnall} 17977a984708SDavid Chisnall 179894e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 17997a984708SDavid Chisnallvoid 180094e3ee44SDavid Chisnall__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() 18017a984708SDavid Chisnall{ 180294e3ee44SDavid Chisnall __f_.~__compressed_pair<_Fp, _Alloc>(); 18037a984708SDavid Chisnall} 18047a984708SDavid Chisnall 180594e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 18067a984708SDavid Chisnallvoid 180794e3ee44SDavid Chisnall__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() 18087a984708SDavid Chisnall{ 1809d72607e9SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap; 1810d72607e9SDimitry Andric typedef allocator_traits<_Ap> _ATraits; 1811d72607e9SDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 181294e3ee44SDavid Chisnall _Ap __a(__f_.second()); 181394e3ee44SDavid Chisnall __f_.~__compressed_pair<_Fp, _Alloc>(); 1814d72607e9SDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 18157a984708SDavid Chisnall} 18167a984708SDavid Chisnall 181794e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 181894e3ee44SDavid Chisnall_Rp 181994e3ee44SDavid Chisnall__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) 18207a984708SDavid Chisnall{ 18217a984708SDavid Chisnall return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); 18227a984708SDavid Chisnall} 18237a984708SDavid Chisnall 18247a984708SDavid Chisnalltemplate <class _Callable> class __packaged_task_function; 18257a984708SDavid Chisnall 182694e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 18270f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)> 18287a984708SDavid Chisnall{ 182994e3ee44SDavid Chisnall typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; 1830cfdf2879SDavid Chisnall typename aligned_storage<3*sizeof(void*)>::type __buf_; 18317a984708SDavid Chisnall __base* __f_; 18327a984708SDavid Chisnall 18337a984708SDavid Chisnallpublic: 183494e3ee44SDavid Chisnall typedef _Rp result_type; 18357a984708SDavid Chisnall 18367a984708SDavid Chisnall // construct/copy/destroy: 18377a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1838936e9439SDimitry Andric __packaged_task_function() _NOEXCEPT : __f_(nullptr) {} 183994e3ee44SDavid Chisnall template<class _Fp> 184094e3ee44SDavid Chisnall __packaged_task_function(_Fp&& __f); 184194e3ee44SDavid Chisnall template<class _Fp, class _Alloc> 184294e3ee44SDavid Chisnall __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); 18437a984708SDavid Chisnall 1844936e9439SDimitry Andric __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; 1845936e9439SDimitry Andric __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; 18467a984708SDavid Chisnall 18477a984708SDavid Chisnall __packaged_task_function(const __packaged_task_function&) = delete; 18487a984708SDavid Chisnall __packaged_task_function& operator=(const __packaged_task_function&) = delete; 18497a984708SDavid Chisnall 18507a984708SDavid Chisnall ~__packaged_task_function(); 18517a984708SDavid Chisnall 1852936e9439SDimitry Andric void swap(__packaged_task_function&) _NOEXCEPT; 18537a984708SDavid Chisnall 18549729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 185594e3ee44SDavid Chisnall _Rp operator()(_ArgTypes...) const; 18567a984708SDavid Chisnall}; 18577a984708SDavid Chisnall 185894e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 1859936e9439SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT 18607a984708SDavid Chisnall{ 18617a984708SDavid Chisnall if (__f.__f_ == nullptr) 18627a984708SDavid Chisnall __f_ = nullptr; 18637a984708SDavid Chisnall else if (__f.__f_ == (__base*)&__f.__buf_) 18647a984708SDavid Chisnall { 18657a984708SDavid Chisnall __f_ = (__base*)&__buf_; 18667a984708SDavid Chisnall __f.__f_->__move_to(__f_); 18677a984708SDavid Chisnall } 18687a984708SDavid Chisnall else 18697a984708SDavid Chisnall { 18707a984708SDavid Chisnall __f_ = __f.__f_; 18717a984708SDavid Chisnall __f.__f_ = nullptr; 18727a984708SDavid Chisnall } 18737a984708SDavid Chisnall} 18747a984708SDavid Chisnall 187594e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 187694e3ee44SDavid Chisnalltemplate <class _Fp> 187794e3ee44SDavid Chisnall__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) 18787a984708SDavid Chisnall : __f_(nullptr) 18797a984708SDavid Chisnall{ 1880d72607e9SDimitry Andric typedef typename remove_reference<typename decay<_Fp>::type>::type _FR; 188194e3ee44SDavid Chisnall typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; 18827a984708SDavid Chisnall if (sizeof(_FF) <= sizeof(__buf_)) 18837a984708SDavid Chisnall { 18847a984708SDavid Chisnall __f_ = (__base*)&__buf_; 188594e3ee44SDavid Chisnall ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); 18867a984708SDavid Chisnall } 18877a984708SDavid Chisnall else 18887a984708SDavid Chisnall { 188994e3ee44SDavid Chisnall typedef allocator<_FF> _Ap; 189094e3ee44SDavid Chisnall _Ap __a; 189194e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 189294e3ee44SDavid Chisnall unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 189394e3ee44SDavid Chisnall ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a)); 18947a984708SDavid Chisnall __f_ = __hold.release(); 18957a984708SDavid Chisnall } 18967a984708SDavid Chisnall} 18977a984708SDavid Chisnall 189894e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 189994e3ee44SDavid Chisnalltemplate <class _Fp, class _Alloc> 190094e3ee44SDavid Chisnall__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function( 190194e3ee44SDavid Chisnall allocator_arg_t, const _Alloc& __a0, _Fp&& __f) 19027a984708SDavid Chisnall : __f_(nullptr) 19037a984708SDavid Chisnall{ 1904d72607e9SDimitry Andric typedef typename remove_reference<typename decay<_Fp>::type>::type _FR; 190594e3ee44SDavid Chisnall typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; 19067a984708SDavid Chisnall if (sizeof(_FF) <= sizeof(__buf_)) 19077a984708SDavid Chisnall { 19087a984708SDavid Chisnall __f_ = (__base*)&__buf_; 190994e3ee44SDavid Chisnall ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); 19107a984708SDavid Chisnall } 19117a984708SDavid Chisnall else 19127a984708SDavid Chisnall { 1913d72607e9SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap; 191494e3ee44SDavid Chisnall _Ap __a(__a0); 191594e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 191694e3ee44SDavid Chisnall unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1917d72607e9SDimitry Andric ::new (static_cast<void*>(_VSTD::addressof(*__hold.get()))) 1918d72607e9SDimitry Andric _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a)); 1919d72607e9SDimitry Andric __f_ = _VSTD::addressof(*__hold.release()); 19207a984708SDavid Chisnall } 19217a984708SDavid Chisnall} 19227a984708SDavid Chisnall 192394e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 192494e3ee44SDavid Chisnall__packaged_task_function<_Rp(_ArgTypes...)>& 1925936e9439SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT 19267a984708SDavid Chisnall{ 19277a984708SDavid Chisnall if (__f_ == (__base*)&__buf_) 19287a984708SDavid Chisnall __f_->destroy(); 19297a984708SDavid Chisnall else if (__f_) 19307a984708SDavid Chisnall __f_->destroy_deallocate(); 19317a984708SDavid Chisnall __f_ = nullptr; 19327a984708SDavid Chisnall if (__f.__f_ == nullptr) 19337a984708SDavid Chisnall __f_ = nullptr; 19347a984708SDavid Chisnall else if (__f.__f_ == (__base*)&__f.__buf_) 19357a984708SDavid Chisnall { 19367a984708SDavid Chisnall __f_ = (__base*)&__buf_; 19377a984708SDavid Chisnall __f.__f_->__move_to(__f_); 19387a984708SDavid Chisnall } 19397a984708SDavid Chisnall else 19407a984708SDavid Chisnall { 19417a984708SDavid Chisnall __f_ = __f.__f_; 19427a984708SDavid Chisnall __f.__f_ = nullptr; 19437a984708SDavid Chisnall } 1944936e9439SDimitry Andric return *this; 19457a984708SDavid Chisnall} 19467a984708SDavid Chisnall 194794e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 194894e3ee44SDavid Chisnall__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() 19497a984708SDavid Chisnall{ 19507a984708SDavid Chisnall if (__f_ == (__base*)&__buf_) 19517a984708SDavid Chisnall __f_->destroy(); 19527a984708SDavid Chisnall else if (__f_) 19537a984708SDavid Chisnall __f_->destroy_deallocate(); 19547a984708SDavid Chisnall} 19557a984708SDavid Chisnall 195694e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 19577a984708SDavid Chisnallvoid 1958936e9439SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT 19597a984708SDavid Chisnall{ 19607a984708SDavid Chisnall if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 19617a984708SDavid Chisnall { 19627a984708SDavid Chisnall typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 19637a984708SDavid Chisnall __base* __t = (__base*)&__tempbuf; 19647a984708SDavid Chisnall __f_->__move_to(__t); 19657a984708SDavid Chisnall __f_->destroy(); 19667a984708SDavid Chisnall __f_ = nullptr; 19677a984708SDavid Chisnall __f.__f_->__move_to((__base*)&__buf_); 19687a984708SDavid Chisnall __f.__f_->destroy(); 19697a984708SDavid Chisnall __f.__f_ = nullptr; 19707a984708SDavid Chisnall __f_ = (__base*)&__buf_; 19717a984708SDavid Chisnall __t->__move_to((__base*)&__f.__buf_); 19727a984708SDavid Chisnall __t->destroy(); 19737a984708SDavid Chisnall __f.__f_ = (__base*)&__f.__buf_; 19747a984708SDavid Chisnall } 19757a984708SDavid Chisnall else if (__f_ == (__base*)&__buf_) 19767a984708SDavid Chisnall { 19777a984708SDavid Chisnall __f_->__move_to((__base*)&__f.__buf_); 19787a984708SDavid Chisnall __f_->destroy(); 19797a984708SDavid Chisnall __f_ = __f.__f_; 19807a984708SDavid Chisnall __f.__f_ = (__base*)&__f.__buf_; 19817a984708SDavid Chisnall } 19827a984708SDavid Chisnall else if (__f.__f_ == (__base*)&__f.__buf_) 19837a984708SDavid Chisnall { 19847a984708SDavid Chisnall __f.__f_->__move_to((__base*)&__buf_); 19857a984708SDavid Chisnall __f.__f_->destroy(); 19867a984708SDavid Chisnall __f.__f_ = __f_; 19877a984708SDavid Chisnall __f_ = (__base*)&__buf_; 19887a984708SDavid Chisnall } 19897a984708SDavid Chisnall else 19907a984708SDavid Chisnall _VSTD::swap(__f_, __f.__f_); 19917a984708SDavid Chisnall} 19927a984708SDavid Chisnall 199394e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 19949729cf09SDimitry Andricinline 199594e3ee44SDavid Chisnall_Rp 199694e3ee44SDavid Chisnall__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const 19977a984708SDavid Chisnall{ 19987a984708SDavid Chisnall return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); 19997a984708SDavid Chisnall} 20007a984708SDavid Chisnall 200194e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 20020f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)> 20037a984708SDavid Chisnall{ 20047a984708SDavid Chisnallpublic: 20057c82a1ecSDimitry Andric typedef _Rp result_type; // extension 20067a984708SDavid Chisnall 20077a984708SDavid Chisnallprivate: 20087a984708SDavid Chisnall __packaged_task_function<result_type(_ArgTypes...)> __f_; 20097a984708SDavid Chisnall promise<result_type> __p_; 20107a984708SDavid Chisnall 20117a984708SDavid Chisnallpublic: 20127a984708SDavid Chisnall // construction and destruction 20137a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2014936e9439SDimitry Andric packaged_task() _NOEXCEPT : __p_(nullptr) {} 20154f7ab58eSDimitry Andric template <class _Fp, 20164f7ab58eSDimitry Andric class = typename enable_if 20174f7ab58eSDimitry Andric < 20184f7ab58eSDimitry Andric !is_same< 20194ba319b5SDimitry Andric typename __uncvref<_Fp>::type, 20204f7ab58eSDimitry Andric packaged_task 20214f7ab58eSDimitry Andric >::value 20224f7ab58eSDimitry Andric >::type 20234f7ab58eSDimitry Andric > 20247a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 202594e3ee44SDavid Chisnall explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} 20264f7ab58eSDimitry Andric template <class _Fp, class _Allocator, 20274f7ab58eSDimitry Andric class = typename enable_if 20284f7ab58eSDimitry Andric < 20294f7ab58eSDimitry Andric !is_same< 20304ba319b5SDimitry Andric typename __uncvref<_Fp>::type, 20314f7ab58eSDimitry Andric packaged_task 20324f7ab58eSDimitry Andric >::value 20334f7ab58eSDimitry Andric >::type 20344f7ab58eSDimitry Andric > 20357a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2036854fa44bSDimitry Andric packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 203794e3ee44SDavid Chisnall : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), 20387a984708SDavid Chisnall __p_(allocator_arg, __a) {} 20397a984708SDavid Chisnall // ~packaged_task() = default; 20407a984708SDavid Chisnall 20417a984708SDavid Chisnall // no copy 2042936e9439SDimitry Andric packaged_task(const packaged_task&) = delete; 2043936e9439SDimitry Andric packaged_task& operator=(const packaged_task&) = delete; 20447a984708SDavid Chisnall 20457a984708SDavid Chisnall // move support 20467a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2047936e9439SDimitry Andric packaged_task(packaged_task&& __other) _NOEXCEPT 20487a984708SDavid Chisnall : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 20497a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2050936e9439SDimitry Andric packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 20517a984708SDavid Chisnall { 20527a984708SDavid Chisnall __f_ = _VSTD::move(__other.__f_); 20537a984708SDavid Chisnall __p_ = _VSTD::move(__other.__p_); 20547a984708SDavid Chisnall return *this; 20557a984708SDavid Chisnall } 20567a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2057936e9439SDimitry Andric void swap(packaged_task& __other) _NOEXCEPT 20587a984708SDavid Chisnall { 20597a984708SDavid Chisnall __f_.swap(__other.__f_); 20607a984708SDavid Chisnall __p_.swap(__other.__p_); 20617a984708SDavid Chisnall } 20627a984708SDavid Chisnall 20637a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2064936e9439SDimitry Andric bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} 20657a984708SDavid Chisnall 20667a984708SDavid Chisnall // result retrieval 20677a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 20687a984708SDavid Chisnall future<result_type> get_future() {return __p_.get_future();} 20697a984708SDavid Chisnall 20707a984708SDavid Chisnall // execution 20717a984708SDavid Chisnall void operator()(_ArgTypes... __args); 20727a984708SDavid Chisnall void make_ready_at_thread_exit(_ArgTypes... __args); 20737a984708SDavid Chisnall 20747a984708SDavid Chisnall void reset(); 20757a984708SDavid Chisnall}; 20767a984708SDavid Chisnall 207794e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 20787a984708SDavid Chisnallvoid 207994e3ee44SDavid Chisnallpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) 20807a984708SDavid Chisnall{ 20817a984708SDavid Chisnall if (__p_.__state_ == nullptr) 20829729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 20837a984708SDavid Chisnall if (__p_.__state_->__has_value()) 20849729cf09SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 20859729cf09SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 20867a984708SDavid Chisnall try 20877a984708SDavid Chisnall { 20887a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 20897a984708SDavid Chisnall __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...)); 20907a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 20917a984708SDavid Chisnall } 20927a984708SDavid Chisnall catch (...) 20937a984708SDavid Chisnall { 20947a984708SDavid Chisnall __p_.set_exception(current_exception()); 20957a984708SDavid Chisnall } 20967a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 20977a984708SDavid Chisnall} 20987a984708SDavid Chisnall 209994e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 21007a984708SDavid Chisnallvoid 210194e3ee44SDavid Chisnallpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) 21027a984708SDavid Chisnall{ 21037a984708SDavid Chisnall if (__p_.__state_ == nullptr) 21049729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 21057a984708SDavid Chisnall if (__p_.__state_->__has_value()) 21069729cf09SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 21079729cf09SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 21087a984708SDavid Chisnall try 21097a984708SDavid Chisnall { 21107a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 21117a984708SDavid Chisnall __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...)); 21127a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 21137a984708SDavid Chisnall } 21147a984708SDavid Chisnall catch (...) 21157a984708SDavid Chisnall { 21167a984708SDavid Chisnall __p_.set_exception_at_thread_exit(current_exception()); 21177a984708SDavid Chisnall } 21187a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 21197a984708SDavid Chisnall} 21207a984708SDavid Chisnall 212194e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes> 21227a984708SDavid Chisnallvoid 212394e3ee44SDavid Chisnallpackaged_task<_Rp(_ArgTypes...)>::reset() 21247a984708SDavid Chisnall{ 21257a984708SDavid Chisnall if (!valid()) 21269729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 21277a984708SDavid Chisnall __p_ = promise<result_type>(); 21287a984708SDavid Chisnall} 21297a984708SDavid Chisnall 21307a984708SDavid Chisnalltemplate<class ..._ArgTypes> 21310f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)> 21327a984708SDavid Chisnall{ 21337a984708SDavid Chisnallpublic: 21347c82a1ecSDimitry Andric typedef void result_type; // extension 21357a984708SDavid Chisnall 21367a984708SDavid Chisnallprivate: 21377a984708SDavid Chisnall __packaged_task_function<result_type(_ArgTypes...)> __f_; 21387a984708SDavid Chisnall promise<result_type> __p_; 21397a984708SDavid Chisnall 21407a984708SDavid Chisnallpublic: 21417a984708SDavid Chisnall // construction and destruction 21427a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2143936e9439SDimitry Andric packaged_task() _NOEXCEPT : __p_(nullptr) {} 21444f7ab58eSDimitry Andric template <class _Fp, 21454f7ab58eSDimitry Andric class = typename enable_if 21464f7ab58eSDimitry Andric < 21474f7ab58eSDimitry Andric !is_same< 21484ba319b5SDimitry Andric typename __uncvref<_Fp>::type, 21494f7ab58eSDimitry Andric packaged_task 21504f7ab58eSDimitry Andric >::value 21514f7ab58eSDimitry Andric >::type 21524f7ab58eSDimitry Andric > 21537a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 215494e3ee44SDavid Chisnall explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} 21554f7ab58eSDimitry Andric template <class _Fp, class _Allocator, 21564f7ab58eSDimitry Andric class = typename enable_if 21574f7ab58eSDimitry Andric < 21584f7ab58eSDimitry Andric !is_same< 21594ba319b5SDimitry Andric typename __uncvref<_Fp>::type, 21604f7ab58eSDimitry Andric packaged_task 21614f7ab58eSDimitry Andric >::value 21624f7ab58eSDimitry Andric >::type 21634f7ab58eSDimitry Andric > 21647a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2165854fa44bSDimitry Andric packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 216694e3ee44SDavid Chisnall : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), 21677a984708SDavid Chisnall __p_(allocator_arg, __a) {} 21687a984708SDavid Chisnall // ~packaged_task() = default; 21697a984708SDavid Chisnall 21707a984708SDavid Chisnall // no copy 2171936e9439SDimitry Andric packaged_task(const packaged_task&) = delete; 2172936e9439SDimitry Andric packaged_task& operator=(const packaged_task&) = delete; 21737a984708SDavid Chisnall 21747a984708SDavid Chisnall // move support 21757a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2176936e9439SDimitry Andric packaged_task(packaged_task&& __other) _NOEXCEPT 21777a984708SDavid Chisnall : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 21787a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2179936e9439SDimitry Andric packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 21807a984708SDavid Chisnall { 21817a984708SDavid Chisnall __f_ = _VSTD::move(__other.__f_); 21827a984708SDavid Chisnall __p_ = _VSTD::move(__other.__p_); 21837a984708SDavid Chisnall return *this; 21847a984708SDavid Chisnall } 21857a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2186936e9439SDimitry Andric void swap(packaged_task& __other) _NOEXCEPT 21877a984708SDavid Chisnall { 21887a984708SDavid Chisnall __f_.swap(__other.__f_); 21897a984708SDavid Chisnall __p_.swap(__other.__p_); 21907a984708SDavid Chisnall } 21917a984708SDavid Chisnall 21927a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2193936e9439SDimitry Andric bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} 21947a984708SDavid Chisnall 21957a984708SDavid Chisnall // result retrieval 21967a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 21977a984708SDavid Chisnall future<result_type> get_future() {return __p_.get_future();} 21987a984708SDavid Chisnall 21997a984708SDavid Chisnall // execution 22007a984708SDavid Chisnall void operator()(_ArgTypes... __args); 22017a984708SDavid Chisnall void make_ready_at_thread_exit(_ArgTypes... __args); 22027a984708SDavid Chisnall 22037a984708SDavid Chisnall void reset(); 22047a984708SDavid Chisnall}; 22057a984708SDavid Chisnall 22067a984708SDavid Chisnalltemplate<class ..._ArgTypes> 22077a984708SDavid Chisnallvoid 22087a984708SDavid Chisnallpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) 22097a984708SDavid Chisnall{ 22107a984708SDavid Chisnall if (__p_.__state_ == nullptr) 22119729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 22127a984708SDavid Chisnall if (__p_.__state_->__has_value()) 22139729cf09SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 22149729cf09SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 22157a984708SDavid Chisnall try 22167a984708SDavid Chisnall { 22177a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 22187a984708SDavid Chisnall __f_(_VSTD::forward<_ArgTypes>(__args)...); 22197a984708SDavid Chisnall __p_.set_value(); 22207a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 22217a984708SDavid Chisnall } 22227a984708SDavid Chisnall catch (...) 22237a984708SDavid Chisnall { 22247a984708SDavid Chisnall __p_.set_exception(current_exception()); 22257a984708SDavid Chisnall } 22267a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 22277a984708SDavid Chisnall} 22287a984708SDavid Chisnall 22297a984708SDavid Chisnalltemplate<class ..._ArgTypes> 22307a984708SDavid Chisnallvoid 22317a984708SDavid Chisnallpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) 22327a984708SDavid Chisnall{ 22337a984708SDavid Chisnall if (__p_.__state_ == nullptr) 22349729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 22357a984708SDavid Chisnall if (__p_.__state_->__has_value()) 22369729cf09SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 22379729cf09SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 22387a984708SDavid Chisnall try 22397a984708SDavid Chisnall { 22407a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 22417a984708SDavid Chisnall __f_(_VSTD::forward<_ArgTypes>(__args)...); 22427a984708SDavid Chisnall __p_.set_value_at_thread_exit(); 22437a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 22447a984708SDavid Chisnall } 22457a984708SDavid Chisnall catch (...) 22467a984708SDavid Chisnall { 22477a984708SDavid Chisnall __p_.set_exception_at_thread_exit(current_exception()); 22487a984708SDavid Chisnall } 22497a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 22507a984708SDavid Chisnall} 22517a984708SDavid Chisnall 22527a984708SDavid Chisnalltemplate<class ..._ArgTypes> 22537a984708SDavid Chisnallvoid 22547a984708SDavid Chisnallpackaged_task<void(_ArgTypes...)>::reset() 22557a984708SDavid Chisnall{ 22567a984708SDavid Chisnall if (!valid()) 22579729cf09SDimitry Andric __throw_future_error(future_errc::no_state); 22587a984708SDavid Chisnall __p_ = promise<result_type>(); 22597a984708SDavid Chisnall} 22607a984708SDavid Chisnall 22617a984708SDavid Chisnalltemplate <class _Callable> 22627a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 22637a984708SDavid Chisnallvoid 2264936e9439SDimitry Andricswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT 22657a984708SDavid Chisnall{ 22667a984708SDavid Chisnall __x.swap(__y); 22677a984708SDavid Chisnall} 22687a984708SDavid Chisnall 22697a984708SDavid Chisnalltemplate <class _Callable, class _Alloc> 2270aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc> 22717a984708SDavid Chisnall : public true_type {}; 22727a984708SDavid Chisnall 227394e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 227494e3ee44SDavid Chisnallfuture<_Rp> 22757a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 227694e3ee44SDavid Chisnall__make_deferred_assoc_state(_Fp&& __f) 22777a984708SDavid Chisnall#else 227894e3ee44SDavid Chisnall__make_deferred_assoc_state(_Fp __f) 22797a984708SDavid Chisnall#endif 22807a984708SDavid Chisnall{ 228194e3ee44SDavid Chisnall unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> 228294e3ee44SDavid Chisnall __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); 228394e3ee44SDavid Chisnall return future<_Rp>(__h.get()); 22847a984708SDavid Chisnall} 22857a984708SDavid Chisnall 228694e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp> 228794e3ee44SDavid Chisnallfuture<_Rp> 22887a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 228994e3ee44SDavid Chisnall__make_async_assoc_state(_Fp&& __f) 22907a984708SDavid Chisnall#else 229194e3ee44SDavid Chisnall__make_async_assoc_state(_Fp __f) 22927a984708SDavid Chisnall#endif 22937a984708SDavid Chisnall{ 229494e3ee44SDavid Chisnall unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> 229594e3ee44SDavid Chisnall __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); 229694e3ee44SDavid Chisnall _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach(); 229794e3ee44SDavid Chisnall return future<_Rp>(__h.get()); 22987a984708SDavid Chisnall} 22997a984708SDavid Chisnall 230094e3ee44SDavid Chisnalltemplate <class _Fp, class... _Args> 23017a984708SDavid Chisnallclass __async_func 23027a984708SDavid Chisnall{ 230394e3ee44SDavid Chisnall tuple<_Fp, _Args...> __f_; 23047a984708SDavid Chisnall 23057a984708SDavid Chisnallpublic: 230694e3ee44SDavid Chisnall typedef typename __invoke_of<_Fp, _Args...>::type _Rp; 23077a984708SDavid Chisnall 23087a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 230994e3ee44SDavid Chisnall explicit __async_func(_Fp&& __f, _Args&&... __args) 23107a984708SDavid Chisnall : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {} 23117a984708SDavid Chisnall 23127a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 23137a984708SDavid Chisnall __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {} 23147a984708SDavid Chisnall 231594e3ee44SDavid Chisnall _Rp operator()() 23167a984708SDavid Chisnall { 23177a984708SDavid Chisnall typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index; 23187a984708SDavid Chisnall return __execute(_Index()); 23197a984708SDavid Chisnall } 23207a984708SDavid Chisnallprivate: 23217a984708SDavid Chisnall template <size_t ..._Indices> 232294e3ee44SDavid Chisnall _Rp 23237a984708SDavid Chisnall __execute(__tuple_indices<_Indices...>) 23247a984708SDavid Chisnall { 23257a984708SDavid Chisnall return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); 23267a984708SDavid Chisnall } 23277a984708SDavid Chisnall}; 23287a984708SDavid Chisnall 23294f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value ) 23304f7ab58eSDimitry Andric{ return (int(__policy) & int(__value)) != 0; } 23314f7ab58eSDimitry Andric 233294e3ee44SDavid Chisnalltemplate <class _Fp, class... _Args> 2333b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 233494e3ee44SDavid Chisnallfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> 233594e3ee44SDavid Chisnallasync(launch __policy, _Fp&& __f, _Args&&... __args) 23367a984708SDavid Chisnall{ 233794e3ee44SDavid Chisnall typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF; 233894e3ee44SDavid Chisnall typedef typename _BF::_Rp _Rp; 23394f7ab58eSDimitry Andric 23404f7ab58eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 23414f7ab58eSDimitry Andric try 23424f7ab58eSDimitry Andric { 23434f7ab58eSDimitry Andric#endif 23444f7ab58eSDimitry Andric if (__does_policy_contain(__policy, launch::async)) 23454f7ab58eSDimitry Andric return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), 23467a984708SDavid Chisnall __decay_copy(_VSTD::forward<_Args>(__args))...)); 23474f7ab58eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 23484f7ab58eSDimitry Andric } 23494f7ab58eSDimitry Andric catch ( ... ) { if (__policy == launch::async) throw ; } 23504f7ab58eSDimitry Andric#endif 23514f7ab58eSDimitry Andric 23524f7ab58eSDimitry Andric if (__does_policy_contain(__policy, launch::deferred)) 23534f7ab58eSDimitry Andric return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), 23547a984708SDavid Chisnall __decay_copy(_VSTD::forward<_Args>(__args))...)); 23554f7ab58eSDimitry Andric return future<_Rp>{}; 23567a984708SDavid Chisnall} 23577a984708SDavid Chisnall 235894e3ee44SDavid Chisnalltemplate <class _Fp, class... _Args> 2359b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY 236094e3ee44SDavid Chisnallfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> 236194e3ee44SDavid Chisnallasync(_Fp&& __f, _Args&&... __args) 23627a984708SDavid Chisnall{ 236394e3ee44SDavid Chisnall return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f), 23647a984708SDavid Chisnall _VSTD::forward<_Args>(__args)...); 23657a984708SDavid Chisnall} 23667a984708SDavid Chisnall 23677a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_VARIADICS 23687a984708SDavid Chisnall 23697a984708SDavid Chisnall// shared_future 23707a984708SDavid Chisnall 237194e3ee44SDavid Chisnalltemplate <class _Rp> 2372aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future 23737a984708SDavid Chisnall{ 237494e3ee44SDavid Chisnall __assoc_state<_Rp>* __state_; 23757a984708SDavid Chisnall 23767a984708SDavid Chisnallpublic: 23777a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2378936e9439SDimitry Andric shared_future() _NOEXCEPT : __state_(nullptr) {} 23797a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2380aed8d94eSDimitry Andric shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 23817a984708SDavid Chisnall {if (__state_) __state_->__add_shared();} 23827a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 23837a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2384936e9439SDimitry Andric shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) 23857a984708SDavid Chisnall {__f.__state_ = nullptr;} 23867a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2387936e9439SDimitry Andric shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 23887a984708SDavid Chisnall {__rhs.__state_ = nullptr;} 23897a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 23907a984708SDavid Chisnall ~shared_future(); 2391aed8d94eSDimitry Andric shared_future& operator=(const shared_future& __rhs) _NOEXCEPT; 23927a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 23937a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2394936e9439SDimitry Andric shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 23957a984708SDavid Chisnall { 23967a984708SDavid Chisnall shared_future(std::move(__rhs)).swap(*this); 23977a984708SDavid Chisnall return *this; 23987a984708SDavid Chisnall } 23997a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 24007a984708SDavid Chisnall 24017a984708SDavid Chisnall // retrieving the value 24027a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 240394e3ee44SDavid Chisnall const _Rp& get() const {return __state_->copy();} 24047a984708SDavid Chisnall 24057a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2406936e9439SDimitry Andric void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 24077a984708SDavid Chisnall 24087a984708SDavid Chisnall // functions to check state 24097a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2410936e9439SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 24117a984708SDavid Chisnall 24127a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24137a984708SDavid Chisnall void wait() const {__state_->wait();} 24147a984708SDavid Chisnall template <class _Rep, class _Period> 24157a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24167a984708SDavid Chisnall future_status 24177a984708SDavid Chisnall wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 24187a984708SDavid Chisnall {return __state_->wait_for(__rel_time);} 24197a984708SDavid Chisnall template <class _Clock, class _Duration> 24207a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24217a984708SDavid Chisnall future_status 24227a984708SDavid Chisnall wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 24237a984708SDavid Chisnall {return __state_->wait_until(__abs_time);} 24247a984708SDavid Chisnall}; 24257a984708SDavid Chisnall 242694e3ee44SDavid Chisnalltemplate <class _Rp> 242794e3ee44SDavid Chisnallshared_future<_Rp>::~shared_future() 24287a984708SDavid Chisnall{ 24297a984708SDavid Chisnall if (__state_) 24307a984708SDavid Chisnall __state_->__release_shared(); 24317a984708SDavid Chisnall} 24327a984708SDavid Chisnall 243394e3ee44SDavid Chisnalltemplate <class _Rp> 243494e3ee44SDavid Chisnallshared_future<_Rp>& 2435aed8d94eSDimitry Andricshared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT 24367a984708SDavid Chisnall{ 24377a984708SDavid Chisnall if (__rhs.__state_) 24387a984708SDavid Chisnall __rhs.__state_->__add_shared(); 24397a984708SDavid Chisnall if (__state_) 24407a984708SDavid Chisnall __state_->__release_shared(); 24417a984708SDavid Chisnall __state_ = __rhs.__state_; 24427a984708SDavid Chisnall return *this; 24437a984708SDavid Chisnall} 24447a984708SDavid Chisnall 244594e3ee44SDavid Chisnalltemplate <class _Rp> 2446aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&> 24477a984708SDavid Chisnall{ 244894e3ee44SDavid Chisnall __assoc_state<_Rp&>* __state_; 24497a984708SDavid Chisnall 24507a984708SDavid Chisnallpublic: 24517a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2452936e9439SDimitry Andric shared_future() _NOEXCEPT : __state_(nullptr) {} 24537a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24547a984708SDavid Chisnall shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) 24557a984708SDavid Chisnall {if (__state_) __state_->__add_shared();} 24567a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 24577a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2458936e9439SDimitry Andric shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) 24597a984708SDavid Chisnall {__f.__state_ = nullptr;} 24607a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2461936e9439SDimitry Andric shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 24627a984708SDavid Chisnall {__rhs.__state_ = nullptr;} 24637a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 24647a984708SDavid Chisnall ~shared_future(); 24657a984708SDavid Chisnall shared_future& operator=(const shared_future& __rhs); 24667a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 24677a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2468936e9439SDimitry Andric shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 24697a984708SDavid Chisnall { 24707a984708SDavid Chisnall shared_future(std::move(__rhs)).swap(*this); 24717a984708SDavid Chisnall return *this; 24727a984708SDavid Chisnall } 24737a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 24747a984708SDavid Chisnall 24757a984708SDavid Chisnall // retrieving the value 24767a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 247794e3ee44SDavid Chisnall _Rp& get() const {return __state_->copy();} 24787a984708SDavid Chisnall 24797a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2480936e9439SDimitry Andric void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 24817a984708SDavid Chisnall 24827a984708SDavid Chisnall // functions to check state 24837a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2484936e9439SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 24857a984708SDavid Chisnall 24867a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24877a984708SDavid Chisnall void wait() const {__state_->wait();} 24887a984708SDavid Chisnall template <class _Rep, class _Period> 24897a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24907a984708SDavid Chisnall future_status 24917a984708SDavid Chisnall wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 24927a984708SDavid Chisnall {return __state_->wait_for(__rel_time);} 24937a984708SDavid Chisnall template <class _Clock, class _Duration> 24947a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24957a984708SDavid Chisnall future_status 24967a984708SDavid Chisnall wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 24977a984708SDavid Chisnall {return __state_->wait_until(__abs_time);} 24987a984708SDavid Chisnall}; 24997a984708SDavid Chisnall 250094e3ee44SDavid Chisnalltemplate <class _Rp> 250194e3ee44SDavid Chisnallshared_future<_Rp&>::~shared_future() 25027a984708SDavid Chisnall{ 25037a984708SDavid Chisnall if (__state_) 25047a984708SDavid Chisnall __state_->__release_shared(); 25057a984708SDavid Chisnall} 25067a984708SDavid Chisnall 250794e3ee44SDavid Chisnalltemplate <class _Rp> 250894e3ee44SDavid Chisnallshared_future<_Rp&>& 250994e3ee44SDavid Chisnallshared_future<_Rp&>::operator=(const shared_future& __rhs) 25107a984708SDavid Chisnall{ 25117a984708SDavid Chisnall if (__rhs.__state_) 25127a984708SDavid Chisnall __rhs.__state_->__add_shared(); 25137a984708SDavid Chisnall if (__state_) 25147a984708SDavid Chisnall __state_->__release_shared(); 25157a984708SDavid Chisnall __state_ = __rhs.__state_; 25167a984708SDavid Chisnall return *this; 25177a984708SDavid Chisnall} 25187a984708SDavid Chisnall 25197a984708SDavid Chisnalltemplate <> 25200f5676f4SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void> 25217a984708SDavid Chisnall{ 25227a984708SDavid Chisnall __assoc_sub_state* __state_; 25237a984708SDavid Chisnall 25247a984708SDavid Chisnallpublic: 25257a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2526936e9439SDimitry Andric shared_future() _NOEXCEPT : __state_(nullptr) {} 25277a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 25287a984708SDavid Chisnall shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) 25297a984708SDavid Chisnall {if (__state_) __state_->__add_shared();} 25307a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 25317a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2532936e9439SDimitry Andric shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) 25337a984708SDavid Chisnall {__f.__state_ = nullptr;} 25347a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2535936e9439SDimitry Andric shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 25367a984708SDavid Chisnall {__rhs.__state_ = nullptr;} 25377a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 25387a984708SDavid Chisnall ~shared_future(); 25397a984708SDavid Chisnall shared_future& operator=(const shared_future& __rhs); 25407a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 25417a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2542936e9439SDimitry Andric shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 25437a984708SDavid Chisnall { 25447a984708SDavid Chisnall shared_future(std::move(__rhs)).swap(*this); 25457a984708SDavid Chisnall return *this; 25467a984708SDavid Chisnall } 25477a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 25487a984708SDavid Chisnall 25497a984708SDavid Chisnall // retrieving the value 25507a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 25517a984708SDavid Chisnall void get() const {__state_->copy();} 25527a984708SDavid Chisnall 25537a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2554936e9439SDimitry Andric void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 25557a984708SDavid Chisnall 25567a984708SDavid Chisnall // functions to check state 25577a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2558936e9439SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 25597a984708SDavid Chisnall 25607a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 25617a984708SDavid Chisnall void wait() const {__state_->wait();} 25627a984708SDavid Chisnall template <class _Rep, class _Period> 25637a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 25647a984708SDavid Chisnall future_status 25657a984708SDavid Chisnall wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 25667a984708SDavid Chisnall {return __state_->wait_for(__rel_time);} 25677a984708SDavid Chisnall template <class _Clock, class _Duration> 25687a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 25697a984708SDavid Chisnall future_status 25707a984708SDavid Chisnall wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 25717a984708SDavid Chisnall {return __state_->wait_until(__abs_time);} 25727a984708SDavid Chisnall}; 25737a984708SDavid Chisnall 257494e3ee44SDavid Chisnalltemplate <class _Rp> 25757a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 25767a984708SDavid Chisnallvoid 2577936e9439SDimitry Andricswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT 25787a984708SDavid Chisnall{ 25797a984708SDavid Chisnall __x.swap(__y); 25807a984708SDavid Chisnall} 25817a984708SDavid Chisnall 258294e3ee44SDavid Chisnalltemplate <class _Rp> 25839729cf09SDimitry Andricinline 258494e3ee44SDavid Chisnallshared_future<_Rp> 2585540d2a8bSDimitry Andricfuture<_Rp>::share() _NOEXCEPT 25867a984708SDavid Chisnall{ 258794e3ee44SDavid Chisnall return shared_future<_Rp>(_VSTD::move(*this)); 25887a984708SDavid Chisnall} 25897a984708SDavid Chisnall 259094e3ee44SDavid Chisnalltemplate <class _Rp> 25919729cf09SDimitry Andricinline 259294e3ee44SDavid Chisnallshared_future<_Rp&> 2593540d2a8bSDimitry Andricfuture<_Rp&>::share() _NOEXCEPT 25947a984708SDavid Chisnall{ 259594e3ee44SDavid Chisnall return shared_future<_Rp&>(_VSTD::move(*this)); 25967a984708SDavid Chisnall} 25977a984708SDavid Chisnall 25987a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 25997a984708SDavid Chisnall 26009729cf09SDimitry Andricinline 26017a984708SDavid Chisnallshared_future<void> 2602540d2a8bSDimitry Andricfuture<void>::share() _NOEXCEPT 26037a984708SDavid Chisnall{ 26047a984708SDavid Chisnall return shared_future<void>(_VSTD::move(*this)); 26057a984708SDavid Chisnall} 26067a984708SDavid Chisnall 26077a984708SDavid Chisnall#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 26087a984708SDavid Chisnall 26097a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD 26107a984708SDavid Chisnall 2611d72607e9SDimitry Andric#endif // !_LIBCPP_HAS_NO_THREADS 2612d72607e9SDimitry Andric 26137a984708SDavid Chisnall#endif // _LIBCPP_FUTURE 2614