1*700637cbSDimitry Andric// -*- C++ -*- 2*700637cbSDimitry Andric//===----------------------------------------------------------------------===// 3*700637cbSDimitry Andric// 4*700637cbSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*700637cbSDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*700637cbSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*700637cbSDimitry Andric// 8*700637cbSDimitry Andric//===----------------------------------------------------------------------===// 9*700637cbSDimitry Andric 10*700637cbSDimitry Andric#ifndef _LIBCPP___CXX03_FUTURE 11*700637cbSDimitry Andric#define _LIBCPP___CXX03_FUTURE 12*700637cbSDimitry Andric 13*700637cbSDimitry Andric/* 14*700637cbSDimitry Andric future synopsis 15*700637cbSDimitry Andric 16*700637cbSDimitry Andricnamespace std 17*700637cbSDimitry Andric{ 18*700637cbSDimitry Andric 19*700637cbSDimitry Andricenum class future_errc 20*700637cbSDimitry Andric{ 21*700637cbSDimitry Andric future_already_retrieved = 1, 22*700637cbSDimitry Andric promise_already_satisfied, 23*700637cbSDimitry Andric no_state, 24*700637cbSDimitry Andric broken_promise 25*700637cbSDimitry Andric}; 26*700637cbSDimitry Andric 27*700637cbSDimitry Andricenum class launch 28*700637cbSDimitry Andric{ 29*700637cbSDimitry Andric async = 1, 30*700637cbSDimitry Andric deferred = 2, 31*700637cbSDimitry Andric any = async | deferred 32*700637cbSDimitry Andric}; 33*700637cbSDimitry Andric 34*700637cbSDimitry Andricenum class future_status 35*700637cbSDimitry Andric{ 36*700637cbSDimitry Andric ready, 37*700637cbSDimitry Andric timeout, 38*700637cbSDimitry Andric deferred 39*700637cbSDimitry Andric}; 40*700637cbSDimitry Andric 41*700637cbSDimitry Andrictemplate <> struct is_error_code_enum<future_errc> : public true_type { }; 42*700637cbSDimitry Andricerror_code make_error_code(future_errc e) noexcept; 43*700637cbSDimitry Andricerror_condition make_error_condition(future_errc e) noexcept; 44*700637cbSDimitry Andric 45*700637cbSDimitry Andricconst error_category& future_category() noexcept; 46*700637cbSDimitry Andric 47*700637cbSDimitry Andricclass future_error : public logic_error { 48*700637cbSDimitry Andricpublic: 49*700637cbSDimitry Andric explicit future_error(future_errc e); // since C++17 50*700637cbSDimitry Andric 51*700637cbSDimitry Andric const error_code& code() const noexcept; 52*700637cbSDimitry Andric const char* what() const noexcept; 53*700637cbSDimitry Andric 54*700637cbSDimitry Andricprivate: 55*700637cbSDimitry Andric error_code ec_; // exposition only 56*700637cbSDimitry Andric}; 57*700637cbSDimitry Andric 58*700637cbSDimitry Andrictemplate <class R> 59*700637cbSDimitry Andricclass promise 60*700637cbSDimitry Andric{ 61*700637cbSDimitry Andricpublic: 62*700637cbSDimitry Andric promise(); 63*700637cbSDimitry Andric template <class Allocator> 64*700637cbSDimitry Andric promise(allocator_arg_t, const Allocator& a); 65*700637cbSDimitry Andric promise(promise&& rhs) noexcept; 66*700637cbSDimitry Andric promise(const promise& rhs) = delete; 67*700637cbSDimitry Andric ~promise(); 68*700637cbSDimitry Andric 69*700637cbSDimitry Andric // assignment 70*700637cbSDimitry Andric promise& operator=(promise&& rhs) noexcept; 71*700637cbSDimitry Andric promise& operator=(const promise& rhs) = delete; 72*700637cbSDimitry Andric void swap(promise& other) noexcept; 73*700637cbSDimitry Andric 74*700637cbSDimitry Andric // retrieving the result 75*700637cbSDimitry Andric future<R> get_future(); 76*700637cbSDimitry Andric 77*700637cbSDimitry Andric // setting the result 78*700637cbSDimitry Andric void set_value(const R& r); 79*700637cbSDimitry Andric void set_value(R&& r); 80*700637cbSDimitry Andric void set_exception(exception_ptr p); 81*700637cbSDimitry Andric 82*700637cbSDimitry Andric // setting the result with deferred notification 83*700637cbSDimitry Andric void set_value_at_thread_exit(const R& r); 84*700637cbSDimitry Andric void set_value_at_thread_exit(R&& r); 85*700637cbSDimitry Andric void set_exception_at_thread_exit(exception_ptr p); 86*700637cbSDimitry Andric}; 87*700637cbSDimitry Andric 88*700637cbSDimitry Andrictemplate <class R> 89*700637cbSDimitry Andricclass promise<R&> 90*700637cbSDimitry Andric{ 91*700637cbSDimitry Andricpublic: 92*700637cbSDimitry Andric promise(); 93*700637cbSDimitry Andric template <class Allocator> 94*700637cbSDimitry Andric promise(allocator_arg_t, const Allocator& a); 95*700637cbSDimitry Andric promise(promise&& rhs) noexcept; 96*700637cbSDimitry Andric promise(const promise& rhs) = delete; 97*700637cbSDimitry Andric ~promise(); 98*700637cbSDimitry Andric 99*700637cbSDimitry Andric // assignment 100*700637cbSDimitry Andric promise& operator=(promise&& rhs) noexcept; 101*700637cbSDimitry Andric promise& operator=(const promise& rhs) = delete; 102*700637cbSDimitry Andric void swap(promise& other) noexcept; 103*700637cbSDimitry Andric 104*700637cbSDimitry Andric // retrieving the result 105*700637cbSDimitry Andric future<R&> get_future(); 106*700637cbSDimitry Andric 107*700637cbSDimitry Andric // setting the result 108*700637cbSDimitry Andric void set_value(R& r); 109*700637cbSDimitry Andric void set_exception(exception_ptr p); 110*700637cbSDimitry Andric 111*700637cbSDimitry Andric // setting the result with deferred notification 112*700637cbSDimitry Andric void set_value_at_thread_exit(R&); 113*700637cbSDimitry Andric void set_exception_at_thread_exit(exception_ptr p); 114*700637cbSDimitry Andric}; 115*700637cbSDimitry Andric 116*700637cbSDimitry Andrictemplate <> 117*700637cbSDimitry Andricclass promise<void> 118*700637cbSDimitry Andric{ 119*700637cbSDimitry Andricpublic: 120*700637cbSDimitry Andric promise(); 121*700637cbSDimitry Andric template <class Allocator> 122*700637cbSDimitry Andric promise(allocator_arg_t, const Allocator& a); 123*700637cbSDimitry Andric promise(promise&& rhs) noexcept; 124*700637cbSDimitry Andric promise(const promise& rhs) = delete; 125*700637cbSDimitry Andric ~promise(); 126*700637cbSDimitry Andric 127*700637cbSDimitry Andric // assignment 128*700637cbSDimitry Andric promise& operator=(promise&& rhs) noexcept; 129*700637cbSDimitry Andric promise& operator=(const promise& rhs) = delete; 130*700637cbSDimitry Andric void swap(promise& other) noexcept; 131*700637cbSDimitry Andric 132*700637cbSDimitry Andric // retrieving the result 133*700637cbSDimitry Andric future<void> get_future(); 134*700637cbSDimitry Andric 135*700637cbSDimitry Andric // setting the result 136*700637cbSDimitry Andric void set_value(); 137*700637cbSDimitry Andric void set_exception(exception_ptr p); 138*700637cbSDimitry Andric 139*700637cbSDimitry Andric // setting the result with deferred notification 140*700637cbSDimitry Andric void set_value_at_thread_exit(); 141*700637cbSDimitry Andric void set_exception_at_thread_exit(exception_ptr p); 142*700637cbSDimitry Andric}; 143*700637cbSDimitry Andric 144*700637cbSDimitry Andrictemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept; 145*700637cbSDimitry Andric 146*700637cbSDimitry Andrictemplate <class R, class Alloc> 147*700637cbSDimitry Andric struct uses_allocator<promise<R>, Alloc> : public true_type {}; 148*700637cbSDimitry Andric 149*700637cbSDimitry Andrictemplate <class R> 150*700637cbSDimitry Andricclass future 151*700637cbSDimitry Andric{ 152*700637cbSDimitry Andricpublic: 153*700637cbSDimitry Andric future() noexcept; 154*700637cbSDimitry Andric future(future&&) noexcept; 155*700637cbSDimitry Andric future(const future& rhs) = delete; 156*700637cbSDimitry Andric ~future(); 157*700637cbSDimitry Andric future& operator=(const future& rhs) = delete; 158*700637cbSDimitry Andric future& operator=(future&&) noexcept; 159*700637cbSDimitry Andric shared_future<R> share() noexcept; 160*700637cbSDimitry Andric 161*700637cbSDimitry Andric // retrieving the value 162*700637cbSDimitry Andric R get(); 163*700637cbSDimitry Andric 164*700637cbSDimitry Andric // functions to check state 165*700637cbSDimitry Andric bool valid() const noexcept; 166*700637cbSDimitry Andric 167*700637cbSDimitry Andric void wait() const; 168*700637cbSDimitry Andric template <class Rep, class Period> 169*700637cbSDimitry Andric future_status 170*700637cbSDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 171*700637cbSDimitry Andric template <class Clock, class Duration> 172*700637cbSDimitry Andric future_status 173*700637cbSDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 174*700637cbSDimitry Andric}; 175*700637cbSDimitry Andric 176*700637cbSDimitry Andrictemplate <class R> 177*700637cbSDimitry Andricclass future<R&> 178*700637cbSDimitry Andric{ 179*700637cbSDimitry Andricpublic: 180*700637cbSDimitry Andric future() noexcept; 181*700637cbSDimitry Andric future(future&&) noexcept; 182*700637cbSDimitry Andric future(const future& rhs) = delete; 183*700637cbSDimitry Andric ~future(); 184*700637cbSDimitry Andric future& operator=(const future& rhs) = delete; 185*700637cbSDimitry Andric future& operator=(future&&) noexcept; 186*700637cbSDimitry Andric shared_future<R&> share() noexcept; 187*700637cbSDimitry Andric 188*700637cbSDimitry Andric // retrieving the value 189*700637cbSDimitry Andric R& get(); 190*700637cbSDimitry Andric 191*700637cbSDimitry Andric // functions to check state 192*700637cbSDimitry Andric bool valid() const noexcept; 193*700637cbSDimitry Andric 194*700637cbSDimitry Andric void wait() const; 195*700637cbSDimitry Andric template <class Rep, class Period> 196*700637cbSDimitry Andric future_status 197*700637cbSDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 198*700637cbSDimitry Andric template <class Clock, class Duration> 199*700637cbSDimitry Andric future_status 200*700637cbSDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 201*700637cbSDimitry Andric}; 202*700637cbSDimitry Andric 203*700637cbSDimitry Andrictemplate <> 204*700637cbSDimitry Andricclass future<void> 205*700637cbSDimitry Andric{ 206*700637cbSDimitry Andricpublic: 207*700637cbSDimitry Andric future() noexcept; 208*700637cbSDimitry Andric future(future&&) noexcept; 209*700637cbSDimitry Andric future(const future& rhs) = delete; 210*700637cbSDimitry Andric ~future(); 211*700637cbSDimitry Andric future& operator=(const future& rhs) = delete; 212*700637cbSDimitry Andric future& operator=(future&&) noexcept; 213*700637cbSDimitry Andric shared_future<void> share() noexcept; 214*700637cbSDimitry Andric 215*700637cbSDimitry Andric // retrieving the value 216*700637cbSDimitry Andric void get(); 217*700637cbSDimitry Andric 218*700637cbSDimitry Andric // functions to check state 219*700637cbSDimitry Andric bool valid() const noexcept; 220*700637cbSDimitry Andric 221*700637cbSDimitry Andric void wait() const; 222*700637cbSDimitry Andric template <class Rep, class Period> 223*700637cbSDimitry Andric future_status 224*700637cbSDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 225*700637cbSDimitry Andric template <class Clock, class Duration> 226*700637cbSDimitry Andric future_status 227*700637cbSDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 228*700637cbSDimitry Andric}; 229*700637cbSDimitry Andric 230*700637cbSDimitry Andrictemplate <class R> 231*700637cbSDimitry Andricclass shared_future 232*700637cbSDimitry Andric{ 233*700637cbSDimitry Andricpublic: 234*700637cbSDimitry Andric shared_future() noexcept; 235*700637cbSDimitry Andric shared_future(const shared_future& rhs); 236*700637cbSDimitry Andric shared_future(future<R>&&) noexcept; 237*700637cbSDimitry Andric shared_future(shared_future&& rhs) noexcept; 238*700637cbSDimitry Andric ~shared_future(); 239*700637cbSDimitry Andric shared_future& operator=(const shared_future& rhs); 240*700637cbSDimitry Andric shared_future& operator=(shared_future&& rhs) noexcept; 241*700637cbSDimitry Andric 242*700637cbSDimitry Andric // retrieving the value 243*700637cbSDimitry Andric const R& get() const; 244*700637cbSDimitry Andric 245*700637cbSDimitry Andric // functions to check state 246*700637cbSDimitry Andric bool valid() const noexcept; 247*700637cbSDimitry Andric 248*700637cbSDimitry Andric void wait() const; 249*700637cbSDimitry Andric template <class Rep, class Period> 250*700637cbSDimitry Andric future_status 251*700637cbSDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 252*700637cbSDimitry Andric template <class Clock, class Duration> 253*700637cbSDimitry Andric future_status 254*700637cbSDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 255*700637cbSDimitry Andric}; 256*700637cbSDimitry Andric 257*700637cbSDimitry Andrictemplate <class R> 258*700637cbSDimitry Andricclass shared_future<R&> 259*700637cbSDimitry Andric{ 260*700637cbSDimitry Andricpublic: 261*700637cbSDimitry Andric shared_future() noexcept; 262*700637cbSDimitry Andric shared_future(const shared_future& rhs); 263*700637cbSDimitry Andric shared_future(future<R&>&&) noexcept; 264*700637cbSDimitry Andric shared_future(shared_future&& rhs) noexcept; 265*700637cbSDimitry Andric ~shared_future(); 266*700637cbSDimitry Andric shared_future& operator=(const shared_future& rhs); 267*700637cbSDimitry Andric shared_future& operator=(shared_future&& rhs) noexcept; 268*700637cbSDimitry Andric 269*700637cbSDimitry Andric // retrieving the value 270*700637cbSDimitry Andric R& get() const; 271*700637cbSDimitry Andric 272*700637cbSDimitry Andric // functions to check state 273*700637cbSDimitry Andric bool valid() const noexcept; 274*700637cbSDimitry Andric 275*700637cbSDimitry Andric void wait() const; 276*700637cbSDimitry Andric template <class Rep, class Period> 277*700637cbSDimitry Andric future_status 278*700637cbSDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 279*700637cbSDimitry Andric template <class Clock, class Duration> 280*700637cbSDimitry Andric future_status 281*700637cbSDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 282*700637cbSDimitry Andric}; 283*700637cbSDimitry Andric 284*700637cbSDimitry Andrictemplate <> 285*700637cbSDimitry Andricclass shared_future<void> 286*700637cbSDimitry Andric{ 287*700637cbSDimitry Andricpublic: 288*700637cbSDimitry Andric shared_future() noexcept; 289*700637cbSDimitry Andric shared_future(const shared_future& rhs); 290*700637cbSDimitry Andric shared_future(future<void>&&) noexcept; 291*700637cbSDimitry Andric shared_future(shared_future&& rhs) noexcept; 292*700637cbSDimitry Andric ~shared_future(); 293*700637cbSDimitry Andric shared_future& operator=(const shared_future& rhs); 294*700637cbSDimitry Andric shared_future& operator=(shared_future&& rhs) noexcept; 295*700637cbSDimitry Andric 296*700637cbSDimitry Andric // retrieving the value 297*700637cbSDimitry Andric void get() const; 298*700637cbSDimitry Andric 299*700637cbSDimitry Andric // functions to check state 300*700637cbSDimitry Andric bool valid() const noexcept; 301*700637cbSDimitry Andric 302*700637cbSDimitry Andric void wait() const; 303*700637cbSDimitry Andric template <class Rep, class Period> 304*700637cbSDimitry Andric future_status 305*700637cbSDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 306*700637cbSDimitry Andric template <class Clock, class Duration> 307*700637cbSDimitry Andric future_status 308*700637cbSDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 309*700637cbSDimitry Andric}; 310*700637cbSDimitry Andric 311*700637cbSDimitry Andrictemplate <class F, class... Args> 312*700637cbSDimitry Andric future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 313*700637cbSDimitry Andric async(F&& f, Args&&... args); 314*700637cbSDimitry Andric 315*700637cbSDimitry Andrictemplate <class F, class... Args> 316*700637cbSDimitry Andric future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 317*700637cbSDimitry Andric async(launch policy, F&& f, Args&&... args); 318*700637cbSDimitry Andric 319*700637cbSDimitry Andrictemplate <class> class packaged_task; // undefined 320*700637cbSDimitry Andric 321*700637cbSDimitry Andrictemplate <class R, class... ArgTypes> 322*700637cbSDimitry Andricclass packaged_task<R(ArgTypes...)> 323*700637cbSDimitry Andric{ 324*700637cbSDimitry Andricpublic: 325*700637cbSDimitry Andric typedef R result_type; // extension 326*700637cbSDimitry Andric 327*700637cbSDimitry Andric // construction and destruction 328*700637cbSDimitry Andric packaged_task() noexcept; 329*700637cbSDimitry Andric template <class F> 330*700637cbSDimitry Andric explicit packaged_task(F&& f); 331*700637cbSDimitry Andric template <class F, class Allocator> 332*700637cbSDimitry Andric packaged_task(allocator_arg_t, const Allocator& a, F&& f); 333*700637cbSDimitry Andric ~packaged_task(); 334*700637cbSDimitry Andric 335*700637cbSDimitry Andric // no copy 336*700637cbSDimitry Andric packaged_task(const packaged_task&) = delete; 337*700637cbSDimitry Andric packaged_task& operator=(const packaged_task&) = delete; 338*700637cbSDimitry Andric 339*700637cbSDimitry Andric // move support 340*700637cbSDimitry Andric packaged_task(packaged_task&& other) noexcept; 341*700637cbSDimitry Andric packaged_task& operator=(packaged_task&& other) noexcept; 342*700637cbSDimitry Andric void swap(packaged_task& other) noexcept; 343*700637cbSDimitry Andric 344*700637cbSDimitry Andric bool valid() const noexcept; 345*700637cbSDimitry Andric 346*700637cbSDimitry Andric // result retrieval 347*700637cbSDimitry Andric future<R> get_future(); 348*700637cbSDimitry Andric 349*700637cbSDimitry Andric // execution 350*700637cbSDimitry Andric void operator()(ArgTypes... ); 351*700637cbSDimitry Andric void make_ready_at_thread_exit(ArgTypes...); 352*700637cbSDimitry Andric 353*700637cbSDimitry Andric void reset(); 354*700637cbSDimitry Andric}; 355*700637cbSDimitry Andric 356*700637cbSDimitry Andrictemplate <class R> 357*700637cbSDimitry Andric void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept; 358*700637cbSDimitry Andric 359*700637cbSDimitry Andrictemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; 360*700637cbSDimitry Andric 361*700637cbSDimitry Andric} // std 362*700637cbSDimitry Andric 363*700637cbSDimitry Andric*/ 364*700637cbSDimitry Andric 365*700637cbSDimitry Andric#include <__cxx03/__config> 366*700637cbSDimitry Andric 367*700637cbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_THREADS) 368*700637cbSDimitry Andric 369*700637cbSDimitry Andric# include <__cxx03/__assert> 370*700637cbSDimitry Andric# include <__cxx03/__chrono/duration.h> 371*700637cbSDimitry Andric# include <__cxx03/__chrono/time_point.h> 372*700637cbSDimitry Andric# include <__cxx03/__exception/exception_ptr.h> 373*700637cbSDimitry Andric# include <__cxx03/__memory/addressof.h> 374*700637cbSDimitry Andric# include <__cxx03/__memory/allocator.h> 375*700637cbSDimitry Andric# include <__cxx03/__memory/allocator_arg_t.h> 376*700637cbSDimitry Andric# include <__cxx03/__memory/allocator_destructor.h> 377*700637cbSDimitry Andric# include <__cxx03/__memory/allocator_traits.h> 378*700637cbSDimitry Andric# include <__cxx03/__memory/compressed_pair.h> 379*700637cbSDimitry Andric# include <__cxx03/__memory/pointer_traits.h> 380*700637cbSDimitry Andric# include <__cxx03/__memory/shared_ptr.h> 381*700637cbSDimitry Andric# include <__cxx03/__memory/unique_ptr.h> 382*700637cbSDimitry Andric# include <__cxx03/__memory/uses_allocator.h> 383*700637cbSDimitry Andric# include <__cxx03/__system_error/error_category.h> 384*700637cbSDimitry Andric# include <__cxx03/__system_error/error_code.h> 385*700637cbSDimitry Andric# include <__cxx03/__system_error/error_condition.h> 386*700637cbSDimitry Andric# include <__cxx03/__type_traits/aligned_storage.h> 387*700637cbSDimitry Andric# include <__cxx03/__type_traits/strip_signature.h> 388*700637cbSDimitry Andric# include <__cxx03/__utility/auto_cast.h> 389*700637cbSDimitry Andric# include <__cxx03/__utility/forward.h> 390*700637cbSDimitry Andric# include <__cxx03/__utility/move.h> 391*700637cbSDimitry Andric# include <__cxx03/mutex> 392*700637cbSDimitry Andric# include <__cxx03/new> 393*700637cbSDimitry Andric# include <__cxx03/stdexcept> 394*700637cbSDimitry Andric# include <__cxx03/thread> 395*700637cbSDimitry Andric# include <__cxx03/version> 396*700637cbSDimitry Andric 397*700637cbSDimitry Andric# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 398*700637cbSDimitry Andric# pragma GCC system_header 399*700637cbSDimitry Andric# endif 400*700637cbSDimitry Andric 401*700637cbSDimitry Andric_LIBCPP_PUSH_MACROS 402*700637cbSDimitry Andric# include <__cxx03/__undef_macros> 403*700637cbSDimitry Andric 404*700637cbSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 405*700637cbSDimitry Andric 406*700637cbSDimitry Andric// enum class future_errc 407*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_errc){ 408*700637cbSDimitry Andric future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise}; 409*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc) 410*700637cbSDimitry Andric 411*700637cbSDimitry Andrictemplate <> 412*700637cbSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {}; 413*700637cbSDimitry Andric 414*700637cbSDimitry Andrictemplate <> 415*700637cbSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type {}; 416*700637cbSDimitry Andric 417*700637cbSDimitry Andric// enum class launch 418*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(launch){async = 1, deferred = 2, any = async | deferred}; 419*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch) 420*700637cbSDimitry Andric 421*700637cbSDimitry Andric// enum class future_status 422*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_status){ready, timeout, deferred}; 423*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status) 424*700637cbSDimitry Andric 425*700637cbSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT; 426*700637cbSDimitry Andric 427*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(future_errc __e) _NOEXCEPT { 428*700637cbSDimitry Andric return error_code(static_cast<int>(__e), future_category()); 429*700637cbSDimitry Andric} 430*700637cbSDimitry Andric 431*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(future_errc __e) _NOEXCEPT { 432*700637cbSDimitry Andric return error_condition(static_cast<int>(__e), future_category()); 433*700637cbSDimitry Andric} 434*700637cbSDimitry Andric 435*700637cbSDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_future_error(future_errc __ev); 436*700637cbSDimitry Andric 437*700637cbSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future_error : public logic_error { 438*700637cbSDimitry Andric error_code __ec_; 439*700637cbSDimitry Andric 440*700637cbSDimitry Andric future_error(error_code); 441*700637cbSDimitry Andric friend void __throw_future_error(future_errc); 442*700637cbSDimitry Andric template <class> 443*700637cbSDimitry Andric friend class promise; 444*700637cbSDimitry Andric 445*700637cbSDimitry Andricpublic: 446*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; } 447*700637cbSDimitry Andric 448*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default; 449*700637cbSDimitry Andric ~future_error() _NOEXCEPT override; 450*700637cbSDimitry Andric}; 451*700637cbSDimitry Andric 452*700637cbSDimitry Andric// Declared above std::future_error 453*700637cbSDimitry Andricvoid __throw_future_error(future_errc __ev) { 454*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 455*700637cbSDimitry Andric throw future_error(make_error_code(__ev)); 456*700637cbSDimitry Andric# else 457*700637cbSDimitry Andric (void)__ev; 458*700637cbSDimitry Andric _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode"); 459*700637cbSDimitry Andric# endif 460*700637cbSDimitry Andric} 461*700637cbSDimitry Andric 462*700637cbSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI __assoc_sub_state : public __shared_count { 463*700637cbSDimitry Andricprotected: 464*700637cbSDimitry Andric exception_ptr __exception_; 465*700637cbSDimitry Andric mutable mutex __mut_; 466*700637cbSDimitry Andric mutable condition_variable __cv_; 467*700637cbSDimitry Andric unsigned __state_; 468*700637cbSDimitry Andric 469*700637cbSDimitry Andric void __on_zero_shared() _NOEXCEPT override; 470*700637cbSDimitry Andric void __sub_wait(unique_lock<mutex>& __lk); 471*700637cbSDimitry Andric 472*700637cbSDimitry Andricpublic: 473*700637cbSDimitry Andric enum { __constructed = 1, __future_attached = 2, ready = 4, deferred = 8 }; 474*700637cbSDimitry Andric 475*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __assoc_sub_state() : __state_(0) {} 476*700637cbSDimitry Andric 477*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __has_value() const { return (__state_ & __constructed) || (__exception_ != nullptr); } 478*700637cbSDimitry Andric 479*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __attach_future() { 480*700637cbSDimitry Andric lock_guard<mutex> __lk(__mut_); 481*700637cbSDimitry Andric bool __has_future_attached = (__state_ & __future_attached) != 0; 482*700637cbSDimitry Andric if (__has_future_attached) 483*700637cbSDimitry Andric __throw_future_error(future_errc::future_already_retrieved); 484*700637cbSDimitry Andric this->__add_shared(); 485*700637cbSDimitry Andric __state_ |= __future_attached; 486*700637cbSDimitry Andric } 487*700637cbSDimitry Andric 488*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __set_deferred() { __state_ |= deferred; } 489*700637cbSDimitry Andric 490*700637cbSDimitry Andric void __make_ready(); 491*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __is_ready() const { return (__state_ & ready) != 0; } 492*700637cbSDimitry Andric 493*700637cbSDimitry Andric void set_value(); 494*700637cbSDimitry Andric void set_value_at_thread_exit(); 495*700637cbSDimitry Andric 496*700637cbSDimitry Andric void set_exception(exception_ptr __p); 497*700637cbSDimitry Andric void set_exception_at_thread_exit(exception_ptr __p); 498*700637cbSDimitry Andric 499*700637cbSDimitry Andric void copy(); 500*700637cbSDimitry Andric 501*700637cbSDimitry Andric void wait(); 502*700637cbSDimitry Andric template <class _Rep, class _Period> 503*700637cbSDimitry Andric future_status _LIBCPP_HIDE_FROM_ABI wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; 504*700637cbSDimitry Andric template <class _Clock, class _Duration> 505*700637cbSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS future_status 506*700637cbSDimitry Andric wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const; 507*700637cbSDimitry Andric 508*700637cbSDimitry Andric virtual void __execute(); 509*700637cbSDimitry Andric}; 510*700637cbSDimitry Andric 511*700637cbSDimitry Andrictemplate <class _Clock, class _Duration> 512*700637cbSDimitry Andricfuture_status __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { 513*700637cbSDimitry Andric unique_lock<mutex> __lk(__mut_); 514*700637cbSDimitry Andric if (__state_ & deferred) 515*700637cbSDimitry Andric return future_status::deferred; 516*700637cbSDimitry Andric while (!(__state_ & ready) && _Clock::now() < __abs_time) 517*700637cbSDimitry Andric __cv_.wait_until(__lk, __abs_time); 518*700637cbSDimitry Andric if (__state_ & ready) 519*700637cbSDimitry Andric return future_status::ready; 520*700637cbSDimitry Andric return future_status::timeout; 521*700637cbSDimitry Andric} 522*700637cbSDimitry Andric 523*700637cbSDimitry Andrictemplate <class _Rep, class _Period> 524*700637cbSDimitry Andricinline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { 525*700637cbSDimitry Andric return wait_until(chrono::steady_clock::now() + __rel_time); 526*700637cbSDimitry Andric} 527*700637cbSDimitry Andric 528*700637cbSDimitry Andrictemplate <class _Rp> 529*700637cbSDimitry Andricclass _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state { 530*700637cbSDimitry Andric typedef __assoc_sub_state base; 531*700637cbSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 532*700637cbSDimitry Andric typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up; 533*700637cbSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 534*700637cbSDimitry Andric 535*700637cbSDimitry Andricprotected: 536*700637cbSDimitry Andric _Up __value_; 537*700637cbSDimitry Andric 538*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; 539*700637cbSDimitry Andric 540*700637cbSDimitry Andricpublic: 541*700637cbSDimitry Andric template <class _Arg> 542*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg); 543*700637cbSDimitry Andric 544*700637cbSDimitry Andric template <class _Arg> 545*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg); 546*700637cbSDimitry Andric 547*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp move(); 548*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy(); 549*700637cbSDimitry Andric}; 550*700637cbSDimitry Andric 551*700637cbSDimitry Andrictemplate <class _Rp> 552*700637cbSDimitry Andricvoid __assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT { 553*700637cbSDimitry Andric if (this->__state_ & base::__constructed) 554*700637cbSDimitry Andric reinterpret_cast<_Rp*>(&__value_)->~_Rp(); 555*700637cbSDimitry Andric delete this; 556*700637cbSDimitry Andric} 557*700637cbSDimitry Andric 558*700637cbSDimitry Andrictemplate <class _Rp> 559*700637cbSDimitry Andrictemplate <class _Arg> 560*700637cbSDimitry Andricvoid __assoc_state<_Rp>::set_value(_Arg&& __arg) { 561*700637cbSDimitry Andric unique_lock<mutex> __lk(this->__mut_); 562*700637cbSDimitry Andric if (this->__has_value()) 563*700637cbSDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 564*700637cbSDimitry Andric ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg)); 565*700637cbSDimitry Andric this->__state_ |= base::__constructed | base::ready; 566*700637cbSDimitry Andric __cv_.notify_all(); 567*700637cbSDimitry Andric} 568*700637cbSDimitry Andric 569*700637cbSDimitry Andrictemplate <class _Rp> 570*700637cbSDimitry Andrictemplate <class _Arg> 571*700637cbSDimitry Andricvoid __assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) { 572*700637cbSDimitry Andric unique_lock<mutex> __lk(this->__mut_); 573*700637cbSDimitry Andric if (this->__has_value()) 574*700637cbSDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 575*700637cbSDimitry Andric ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg)); 576*700637cbSDimitry Andric this->__state_ |= base::__constructed; 577*700637cbSDimitry Andric __thread_local_data()->__make_ready_at_thread_exit(this); 578*700637cbSDimitry Andric} 579*700637cbSDimitry Andric 580*700637cbSDimitry Andrictemplate <class _Rp> 581*700637cbSDimitry Andric_Rp __assoc_state<_Rp>::move() { 582*700637cbSDimitry Andric unique_lock<mutex> __lk(this->__mut_); 583*700637cbSDimitry Andric this->__sub_wait(__lk); 584*700637cbSDimitry Andric if (this->__exception_ != nullptr) 585*700637cbSDimitry Andric std::rethrow_exception(this->__exception_); 586*700637cbSDimitry Andric return std::move(*reinterpret_cast<_Rp*>(&__value_)); 587*700637cbSDimitry Andric} 588*700637cbSDimitry Andric 589*700637cbSDimitry Andrictemplate <class _Rp> 590*700637cbSDimitry Andric__add_lvalue_reference_t<_Rp> __assoc_state<_Rp>::copy() { 591*700637cbSDimitry Andric unique_lock<mutex> __lk(this->__mut_); 592*700637cbSDimitry Andric this->__sub_wait(__lk); 593*700637cbSDimitry Andric if (this->__exception_ != nullptr) 594*700637cbSDimitry Andric std::rethrow_exception(this->__exception_); 595*700637cbSDimitry Andric return *reinterpret_cast<_Rp*>(&__value_); 596*700637cbSDimitry Andric} 597*700637cbSDimitry Andric 598*700637cbSDimitry Andrictemplate <class _Rp> 599*700637cbSDimitry Andricclass __assoc_state<_Rp&> : public __assoc_sub_state { 600*700637cbSDimitry Andric typedef __assoc_sub_state base; 601*700637cbSDimitry Andric typedef _Rp* _Up; 602*700637cbSDimitry Andric 603*700637cbSDimitry Andricprotected: 604*700637cbSDimitry Andric _Up __value_; 605*700637cbSDimitry Andric 606*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; 607*700637cbSDimitry Andric 608*700637cbSDimitry Andricpublic: 609*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg); 610*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg); 611*700637cbSDimitry Andric 612*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp& copy(); 613*700637cbSDimitry Andric}; 614*700637cbSDimitry Andric 615*700637cbSDimitry Andrictemplate <class _Rp> 616*700637cbSDimitry Andricvoid __assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT { 617*700637cbSDimitry Andric delete this; 618*700637cbSDimitry Andric} 619*700637cbSDimitry Andric 620*700637cbSDimitry Andrictemplate <class _Rp> 621*700637cbSDimitry Andricvoid __assoc_state<_Rp&>::set_value(_Rp& __arg) { 622*700637cbSDimitry Andric unique_lock<mutex> __lk(this->__mut_); 623*700637cbSDimitry Andric if (this->__has_value()) 624*700637cbSDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 625*700637cbSDimitry Andric __value_ = std::addressof(__arg); 626*700637cbSDimitry Andric this->__state_ |= base::__constructed | base::ready; 627*700637cbSDimitry Andric __cv_.notify_all(); 628*700637cbSDimitry Andric} 629*700637cbSDimitry Andric 630*700637cbSDimitry Andrictemplate <class _Rp> 631*700637cbSDimitry Andricvoid __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) { 632*700637cbSDimitry Andric unique_lock<mutex> __lk(this->__mut_); 633*700637cbSDimitry Andric if (this->__has_value()) 634*700637cbSDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 635*700637cbSDimitry Andric __value_ = std::addressof(__arg); 636*700637cbSDimitry Andric this->__state_ |= base::__constructed; 637*700637cbSDimitry Andric __thread_local_data()->__make_ready_at_thread_exit(this); 638*700637cbSDimitry Andric} 639*700637cbSDimitry Andric 640*700637cbSDimitry Andrictemplate <class _Rp> 641*700637cbSDimitry Andric_Rp& __assoc_state<_Rp&>::copy() { 642*700637cbSDimitry Andric unique_lock<mutex> __lk(this->__mut_); 643*700637cbSDimitry Andric this->__sub_wait(__lk); 644*700637cbSDimitry Andric if (this->__exception_ != nullptr) 645*700637cbSDimitry Andric std::rethrow_exception(this->__exception_); 646*700637cbSDimitry Andric return *__value_; 647*700637cbSDimitry Andric} 648*700637cbSDimitry Andric 649*700637cbSDimitry Andrictemplate <class _Rp, class _Alloc> 650*700637cbSDimitry Andricclass __assoc_state_alloc : public __assoc_state<_Rp> { 651*700637cbSDimitry Andric typedef __assoc_state<_Rp> base; 652*700637cbSDimitry Andric _Alloc __alloc_; 653*700637cbSDimitry Andric 654*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; 655*700637cbSDimitry Andric 656*700637cbSDimitry Andricpublic: 657*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {} 658*700637cbSDimitry Andric}; 659*700637cbSDimitry Andric 660*700637cbSDimitry Andrictemplate <class _Rp, class _Alloc> 661*700637cbSDimitry Andricvoid __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT { 662*700637cbSDimitry Andric if (this->__state_ & base::__constructed) 663*700637cbSDimitry Andric reinterpret_cast<_Rp*>(std::addressof(this->__value_))->~_Rp(); 664*700637cbSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; 665*700637cbSDimitry Andric typedef allocator_traits<_Al> _ATraits; 666*700637cbSDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 667*700637cbSDimitry Andric _Al __a(__alloc_); 668*700637cbSDimitry Andric this->~__assoc_state_alloc(); 669*700637cbSDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 670*700637cbSDimitry Andric} 671*700637cbSDimitry Andric 672*700637cbSDimitry Andrictemplate <class _Rp, class _Alloc> 673*700637cbSDimitry Andricclass __assoc_state_alloc<_Rp&, _Alloc> : public __assoc_state<_Rp&> { 674*700637cbSDimitry Andric typedef __assoc_state<_Rp&> base; 675*700637cbSDimitry Andric _Alloc __alloc_; 676*700637cbSDimitry Andric 677*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; 678*700637cbSDimitry Andric 679*700637cbSDimitry Andricpublic: 680*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {} 681*700637cbSDimitry Andric}; 682*700637cbSDimitry Andric 683*700637cbSDimitry Andrictemplate <class _Rp, class _Alloc> 684*700637cbSDimitry Andricvoid __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT { 685*700637cbSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; 686*700637cbSDimitry Andric typedef allocator_traits<_Al> _ATraits; 687*700637cbSDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 688*700637cbSDimitry Andric _Al __a(__alloc_); 689*700637cbSDimitry Andric this->~__assoc_state_alloc(); 690*700637cbSDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 691*700637cbSDimitry Andric} 692*700637cbSDimitry Andric 693*700637cbSDimitry Andrictemplate <class _Alloc> 694*700637cbSDimitry Andricclass __assoc_sub_state_alloc : public __assoc_sub_state { 695*700637cbSDimitry Andric typedef __assoc_sub_state base; 696*700637cbSDimitry Andric _Alloc __alloc_; 697*700637cbSDimitry Andric 698*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; 699*700637cbSDimitry Andric 700*700637cbSDimitry Andricpublic: 701*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __assoc_sub_state_alloc(const _Alloc& __a) : __alloc_(__a) {} 702*700637cbSDimitry Andric}; 703*700637cbSDimitry Andric 704*700637cbSDimitry Andrictemplate <class _Alloc> 705*700637cbSDimitry Andricvoid __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT { 706*700637cbSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al; 707*700637cbSDimitry Andric typedef allocator_traits<_Al> _ATraits; 708*700637cbSDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 709*700637cbSDimitry Andric _Al __a(__alloc_); 710*700637cbSDimitry Andric this->~__assoc_sub_state_alloc(); 711*700637cbSDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 712*700637cbSDimitry Andric} 713*700637cbSDimitry Andric 714*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 715*700637cbSDimitry Andricclass __deferred_assoc_state : public __assoc_state<_Rp> { 716*700637cbSDimitry Andric typedef __assoc_state<_Rp> base; 717*700637cbSDimitry Andric 718*700637cbSDimitry Andric _Fp __func_; 719*700637cbSDimitry Andric 720*700637cbSDimitry Andricpublic: 721*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f); 722*700637cbSDimitry Andric 723*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute(); 724*700637cbSDimitry Andric}; 725*700637cbSDimitry Andric 726*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 727*700637cbSDimitry Andricinline __deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) { 728*700637cbSDimitry Andric this->__set_deferred(); 729*700637cbSDimitry Andric} 730*700637cbSDimitry Andric 731*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 732*700637cbSDimitry Andricvoid __deferred_assoc_state<_Rp, _Fp>::__execute() { 733*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 734*700637cbSDimitry Andric try { 735*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 736*700637cbSDimitry Andric this->set_value(__func_()); 737*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 738*700637cbSDimitry Andric } catch (...) { 739*700637cbSDimitry Andric this->set_exception(current_exception()); 740*700637cbSDimitry Andric } 741*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 742*700637cbSDimitry Andric} 743*700637cbSDimitry Andric 744*700637cbSDimitry Andrictemplate <class _Fp> 745*700637cbSDimitry Andricclass __deferred_assoc_state<void, _Fp> : public __assoc_sub_state { 746*700637cbSDimitry Andric typedef __assoc_sub_state base; 747*700637cbSDimitry Andric 748*700637cbSDimitry Andric _Fp __func_; 749*700637cbSDimitry Andric 750*700637cbSDimitry Andricpublic: 751*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f); 752*700637cbSDimitry Andric 753*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override; 754*700637cbSDimitry Andric}; 755*700637cbSDimitry Andric 756*700637cbSDimitry Andrictemplate <class _Fp> 757*700637cbSDimitry Andricinline __deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) { 758*700637cbSDimitry Andric this->__set_deferred(); 759*700637cbSDimitry Andric} 760*700637cbSDimitry Andric 761*700637cbSDimitry Andrictemplate <class _Fp> 762*700637cbSDimitry Andricvoid __deferred_assoc_state<void, _Fp>::__execute() { 763*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 764*700637cbSDimitry Andric try { 765*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 766*700637cbSDimitry Andric __func_(); 767*700637cbSDimitry Andric this->set_value(); 768*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 769*700637cbSDimitry Andric } catch (...) { 770*700637cbSDimitry Andric this->set_exception(current_exception()); 771*700637cbSDimitry Andric } 772*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 773*700637cbSDimitry Andric} 774*700637cbSDimitry Andric 775*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 776*700637cbSDimitry Andricclass __async_assoc_state : public __assoc_state<_Rp> { 777*700637cbSDimitry Andric typedef __assoc_state<_Rp> base; 778*700637cbSDimitry Andric 779*700637cbSDimitry Andric _Fp __func_; 780*700637cbSDimitry Andric 781*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; 782*700637cbSDimitry Andric 783*700637cbSDimitry Andricpublic: 784*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f); 785*700637cbSDimitry Andric 786*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute(); 787*700637cbSDimitry Andric}; 788*700637cbSDimitry Andric 789*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 790*700637cbSDimitry Andricinline __async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {} 791*700637cbSDimitry Andric 792*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 793*700637cbSDimitry Andricvoid __async_assoc_state<_Rp, _Fp>::__execute() { 794*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 795*700637cbSDimitry Andric try { 796*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 797*700637cbSDimitry Andric this->set_value(__func_()); 798*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 799*700637cbSDimitry Andric } catch (...) { 800*700637cbSDimitry Andric this->set_exception(current_exception()); 801*700637cbSDimitry Andric } 802*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 803*700637cbSDimitry Andric} 804*700637cbSDimitry Andric 805*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 806*700637cbSDimitry Andricvoid __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT { 807*700637cbSDimitry Andric this->wait(); 808*700637cbSDimitry Andric base::__on_zero_shared(); 809*700637cbSDimitry Andric} 810*700637cbSDimitry Andric 811*700637cbSDimitry Andrictemplate <class _Fp> 812*700637cbSDimitry Andricclass __async_assoc_state<void, _Fp> : public __assoc_sub_state { 813*700637cbSDimitry Andric typedef __assoc_sub_state base; 814*700637cbSDimitry Andric 815*700637cbSDimitry Andric _Fp __func_; 816*700637cbSDimitry Andric 817*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; 818*700637cbSDimitry Andric 819*700637cbSDimitry Andricpublic: 820*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f); 821*700637cbSDimitry Andric 822*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override; 823*700637cbSDimitry Andric}; 824*700637cbSDimitry Andric 825*700637cbSDimitry Andrictemplate <class _Fp> 826*700637cbSDimitry Andricinline __async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {} 827*700637cbSDimitry Andric 828*700637cbSDimitry Andrictemplate <class _Fp> 829*700637cbSDimitry Andricvoid __async_assoc_state<void, _Fp>::__execute() { 830*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 831*700637cbSDimitry Andric try { 832*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 833*700637cbSDimitry Andric __func_(); 834*700637cbSDimitry Andric this->set_value(); 835*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 836*700637cbSDimitry Andric } catch (...) { 837*700637cbSDimitry Andric this->set_exception(current_exception()); 838*700637cbSDimitry Andric } 839*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 840*700637cbSDimitry Andric} 841*700637cbSDimitry Andric 842*700637cbSDimitry Andrictemplate <class _Fp> 843*700637cbSDimitry Andricvoid __async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT { 844*700637cbSDimitry Andric this->wait(); 845*700637cbSDimitry Andric base::__on_zero_shared(); 846*700637cbSDimitry Andric} 847*700637cbSDimitry Andric 848*700637cbSDimitry Andrictemplate <class _Rp> 849*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise; 850*700637cbSDimitry Andrictemplate <class _Rp> 851*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future; 852*700637cbSDimitry Andric 853*700637cbSDimitry Andric// future 854*700637cbSDimitry Andric 855*700637cbSDimitry Andrictemplate <class _Rp> 856*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future; 857*700637cbSDimitry Andric 858*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 859*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f); 860*700637cbSDimitry Andric 861*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 862*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f); 863*700637cbSDimitry Andric 864*700637cbSDimitry Andrictemplate <class _Rp> 865*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future { 866*700637cbSDimitry Andric __assoc_state<_Rp>* __state_; 867*700637cbSDimitry Andric 868*700637cbSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state); 869*700637cbSDimitry Andric 870*700637cbSDimitry Andric template <class> 871*700637cbSDimitry Andric friend class promise; 872*700637cbSDimitry Andric template <class> 873*700637cbSDimitry Andric friend class shared_future; 874*700637cbSDimitry Andric 875*700637cbSDimitry Andric template <class _R1, class _Fp> 876*700637cbSDimitry Andric friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 877*700637cbSDimitry Andric template <class _R1, class _Fp> 878*700637cbSDimitry Andric friend future<_R1> __make_async_assoc_state(_Fp&& __f); 879*700637cbSDimitry Andric 880*700637cbSDimitry Andricpublic: 881*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {} 882*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } 883*700637cbSDimitry Andric future(const future&) = delete; 884*700637cbSDimitry Andric future& operator=(const future&) = delete; 885*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT { 886*700637cbSDimitry Andric future(std::move(__rhs)).swap(*this); 887*700637cbSDimitry Andric return *this; 888*700637cbSDimitry Andric } 889*700637cbSDimitry Andric 890*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~future(); 891*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future<_Rp> share() _NOEXCEPT; 892*700637cbSDimitry Andric 893*700637cbSDimitry Andric // retrieving the value 894*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp get(); 895*700637cbSDimitry Andric 896*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } 897*700637cbSDimitry Andric 898*700637cbSDimitry Andric // functions to check state 899*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } 900*700637cbSDimitry Andric 901*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } 902*700637cbSDimitry Andric template <class _Rep, class _Period> 903*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { 904*700637cbSDimitry Andric return __state_->wait_for(__rel_time); 905*700637cbSDimitry Andric } 906*700637cbSDimitry Andric template <class _Clock, class _Duration> 907*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { 908*700637cbSDimitry Andric return __state_->wait_until(__abs_time); 909*700637cbSDimitry Andric } 910*700637cbSDimitry Andric}; 911*700637cbSDimitry Andric 912*700637cbSDimitry Andrictemplate <class _Rp> 913*700637cbSDimitry Andricfuture<_Rp>::future(__assoc_state<_Rp>* __state) : __state_(__state) { 914*700637cbSDimitry Andric __state_->__attach_future(); 915*700637cbSDimitry Andric} 916*700637cbSDimitry Andric 917*700637cbSDimitry Andricstruct __release_shared_count { 918*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) { __p->__release_shared(); } 919*700637cbSDimitry Andric}; 920*700637cbSDimitry Andric 921*700637cbSDimitry Andrictemplate <class _Rp> 922*700637cbSDimitry Andricfuture<_Rp>::~future() { 923*700637cbSDimitry Andric if (__state_) 924*700637cbSDimitry Andric __state_->__release_shared(); 925*700637cbSDimitry Andric} 926*700637cbSDimitry Andric 927*700637cbSDimitry Andrictemplate <class _Rp> 928*700637cbSDimitry Andric_Rp future<_Rp>::get() { 929*700637cbSDimitry Andric unique_ptr<__shared_count, __release_shared_count> __guard(__state_); 930*700637cbSDimitry Andric __assoc_state<_Rp>* __s = __state_; 931*700637cbSDimitry Andric __state_ = nullptr; 932*700637cbSDimitry Andric return __s->move(); 933*700637cbSDimitry Andric} 934*700637cbSDimitry Andric 935*700637cbSDimitry Andrictemplate <class _Rp> 936*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future<_Rp&> { 937*700637cbSDimitry Andric __assoc_state<_Rp&>* __state_; 938*700637cbSDimitry Andric 939*700637cbSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state); 940*700637cbSDimitry Andric 941*700637cbSDimitry Andric template <class> 942*700637cbSDimitry Andric friend class promise; 943*700637cbSDimitry Andric template <class> 944*700637cbSDimitry Andric friend class shared_future; 945*700637cbSDimitry Andric 946*700637cbSDimitry Andric template <class _R1, class _Fp> 947*700637cbSDimitry Andric friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 948*700637cbSDimitry Andric template <class _R1, class _Fp> 949*700637cbSDimitry Andric friend future<_R1> __make_async_assoc_state(_Fp&& __f); 950*700637cbSDimitry Andric 951*700637cbSDimitry Andricpublic: 952*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {} 953*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } 954*700637cbSDimitry Andric future(const future&) = delete; 955*700637cbSDimitry Andric future& operator=(const future&) = delete; 956*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT { 957*700637cbSDimitry Andric future(std::move(__rhs)).swap(*this); 958*700637cbSDimitry Andric return *this; 959*700637cbSDimitry Andric } 960*700637cbSDimitry Andric 961*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~future(); 962*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future<_Rp&> share() _NOEXCEPT; 963*700637cbSDimitry Andric 964*700637cbSDimitry Andric // retrieving the value 965*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp& get(); 966*700637cbSDimitry Andric 967*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } 968*700637cbSDimitry Andric 969*700637cbSDimitry Andric // functions to check state 970*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } 971*700637cbSDimitry Andric 972*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } 973*700637cbSDimitry Andric template <class _Rep, class _Period> 974*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { 975*700637cbSDimitry Andric return __state_->wait_for(__rel_time); 976*700637cbSDimitry Andric } 977*700637cbSDimitry Andric template <class _Clock, class _Duration> 978*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { 979*700637cbSDimitry Andric return __state_->wait_until(__abs_time); 980*700637cbSDimitry Andric } 981*700637cbSDimitry Andric}; 982*700637cbSDimitry Andric 983*700637cbSDimitry Andrictemplate <class _Rp> 984*700637cbSDimitry Andricfuture<_Rp&>::future(__assoc_state<_Rp&>* __state) : __state_(__state) { 985*700637cbSDimitry Andric __state_->__attach_future(); 986*700637cbSDimitry Andric} 987*700637cbSDimitry Andric 988*700637cbSDimitry Andrictemplate <class _Rp> 989*700637cbSDimitry Andricfuture<_Rp&>::~future() { 990*700637cbSDimitry Andric if (__state_) 991*700637cbSDimitry Andric __state_->__release_shared(); 992*700637cbSDimitry Andric} 993*700637cbSDimitry Andric 994*700637cbSDimitry Andrictemplate <class _Rp> 995*700637cbSDimitry Andric_Rp& future<_Rp&>::get() { 996*700637cbSDimitry Andric unique_ptr<__shared_count, __release_shared_count> __guard(__state_); 997*700637cbSDimitry Andric __assoc_state<_Rp&>* __s = __state_; 998*700637cbSDimitry Andric __state_ = nullptr; 999*700637cbSDimitry Andric return __s->copy(); 1000*700637cbSDimitry Andric} 1001*700637cbSDimitry Andric 1002*700637cbSDimitry Andrictemplate <> 1003*700637cbSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future<void> { 1004*700637cbSDimitry Andric __assoc_sub_state* __state_; 1005*700637cbSDimitry Andric 1006*700637cbSDimitry Andric explicit future(__assoc_sub_state* __state); 1007*700637cbSDimitry Andric 1008*700637cbSDimitry Andric template <class> 1009*700637cbSDimitry Andric friend class promise; 1010*700637cbSDimitry Andric template <class> 1011*700637cbSDimitry Andric friend class shared_future; 1012*700637cbSDimitry Andric 1013*700637cbSDimitry Andric template <class _R1, class _Fp> 1014*700637cbSDimitry Andric friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 1015*700637cbSDimitry Andric template <class _R1, class _Fp> 1016*700637cbSDimitry Andric friend future<_R1> __make_async_assoc_state(_Fp&& __f); 1017*700637cbSDimitry Andric 1018*700637cbSDimitry Andricpublic: 1019*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {} 1020*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } 1021*700637cbSDimitry Andric future(const future&) = delete; 1022*700637cbSDimitry Andric future& operator=(const future&) = delete; 1023*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT { 1024*700637cbSDimitry Andric future(std::move(__rhs)).swap(*this); 1025*700637cbSDimitry Andric return *this; 1026*700637cbSDimitry Andric } 1027*700637cbSDimitry Andric 1028*700637cbSDimitry Andric ~future(); 1029*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future<void> share() _NOEXCEPT; 1030*700637cbSDimitry Andric 1031*700637cbSDimitry Andric // retrieving the value 1032*700637cbSDimitry Andric void get(); 1033*700637cbSDimitry Andric 1034*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } 1035*700637cbSDimitry Andric 1036*700637cbSDimitry Andric // functions to check state 1037*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } 1038*700637cbSDimitry Andric 1039*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } 1040*700637cbSDimitry Andric template <class _Rep, class _Period> 1041*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { 1042*700637cbSDimitry Andric return __state_->wait_for(__rel_time); 1043*700637cbSDimitry Andric } 1044*700637cbSDimitry Andric template <class _Clock, class _Duration> 1045*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { 1046*700637cbSDimitry Andric return __state_->wait_until(__abs_time); 1047*700637cbSDimitry Andric } 1048*700637cbSDimitry Andric}; 1049*700637cbSDimitry Andric 1050*700637cbSDimitry Andrictemplate <class _Rp> 1051*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT { 1052*700637cbSDimitry Andric __x.swap(__y); 1053*700637cbSDimitry Andric} 1054*700637cbSDimitry Andric 1055*700637cbSDimitry Andric// promise<R> 1056*700637cbSDimitry Andric 1057*700637cbSDimitry Andrictemplate <class _Callable> 1058*700637cbSDimitry Andricclass packaged_task; 1059*700637cbSDimitry Andric 1060*700637cbSDimitry Andrictemplate <class _Rp> 1061*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise { 1062*700637cbSDimitry Andric __assoc_state<_Rp>* __state_; 1063*700637cbSDimitry Andric 1064*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1065*700637cbSDimitry Andric 1066*700637cbSDimitry Andric template <class> 1067*700637cbSDimitry Andric friend class packaged_task; 1068*700637cbSDimitry Andric 1069*700637cbSDimitry Andricpublic: 1070*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI promise(); 1071*700637cbSDimitry Andric template <class _Alloc> 1072*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a); 1073*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } 1074*700637cbSDimitry Andric promise(const promise& __rhs) = delete; 1075*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~promise(); 1076*700637cbSDimitry Andric 1077*700637cbSDimitry Andric // assignment 1078*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT { 1079*700637cbSDimitry Andric promise(std::move(__rhs)).swap(*this); 1080*700637cbSDimitry Andric return *this; 1081*700637cbSDimitry Andric } 1082*700637cbSDimitry Andric promise& operator=(const promise& __rhs) = delete; 1083*700637cbSDimitry Andric 1084*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } 1085*700637cbSDimitry Andric 1086*700637cbSDimitry Andric // retrieving the result 1087*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future(); 1088*700637cbSDimitry Andric 1089*700637cbSDimitry Andric // setting the result 1090*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r); 1091*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r); 1092*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p); 1093*700637cbSDimitry Andric 1094*700637cbSDimitry Andric // setting the result with deferred notification 1095*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r); 1096*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r); 1097*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p); 1098*700637cbSDimitry Andric}; 1099*700637cbSDimitry Andric 1100*700637cbSDimitry Andrictemplate <class _Rp> 1101*700637cbSDimitry Andricpromise<_Rp>::promise() : __state_(new __assoc_state<_Rp>) {} 1102*700637cbSDimitry Andric 1103*700637cbSDimitry Andrictemplate <class _Rp> 1104*700637cbSDimitry Andrictemplate <class _Alloc> 1105*700637cbSDimitry Andricpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) { 1106*700637cbSDimitry Andric typedef __assoc_state_alloc<_Rp, _Alloc> _State; 1107*700637cbSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; 1108*700637cbSDimitry Andric typedef __allocator_destructor<_A2> _D2; 1109*700637cbSDimitry Andric _A2 __a(__a0); 1110*700637cbSDimitry Andric unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1111*700637cbSDimitry Andric ::new ((void*)std::addressof(*__hold.get())) _State(__a0); 1112*700637cbSDimitry Andric __state_ = std::addressof(*__hold.release()); 1113*700637cbSDimitry Andric} 1114*700637cbSDimitry Andric 1115*700637cbSDimitry Andrictemplate <class _Rp> 1116*700637cbSDimitry Andricpromise<_Rp>::~promise() { 1117*700637cbSDimitry Andric if (__state_) { 1118*700637cbSDimitry Andric if (!__state_->__has_value() && __state_->use_count() > 1) 1119*700637cbSDimitry Andric __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise)))); 1120*700637cbSDimitry Andric __state_->__release_shared(); 1121*700637cbSDimitry Andric } 1122*700637cbSDimitry Andric} 1123*700637cbSDimitry Andric 1124*700637cbSDimitry Andrictemplate <class _Rp> 1125*700637cbSDimitry Andricfuture<_Rp> promise<_Rp>::get_future() { 1126*700637cbSDimitry Andric if (__state_ == nullptr) 1127*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1128*700637cbSDimitry Andric return future<_Rp>(__state_); 1129*700637cbSDimitry Andric} 1130*700637cbSDimitry Andric 1131*700637cbSDimitry Andrictemplate <class _Rp> 1132*700637cbSDimitry Andricvoid promise<_Rp>::set_value(const _Rp& __r) { 1133*700637cbSDimitry Andric if (__state_ == nullptr) 1134*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1135*700637cbSDimitry Andric __state_->set_value(__r); 1136*700637cbSDimitry Andric} 1137*700637cbSDimitry Andric 1138*700637cbSDimitry Andrictemplate <class _Rp> 1139*700637cbSDimitry Andricvoid promise<_Rp>::set_value(_Rp&& __r) { 1140*700637cbSDimitry Andric if (__state_ == nullptr) 1141*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1142*700637cbSDimitry Andric __state_->set_value(std::move(__r)); 1143*700637cbSDimitry Andric} 1144*700637cbSDimitry Andric 1145*700637cbSDimitry Andrictemplate <class _Rp> 1146*700637cbSDimitry Andricvoid promise<_Rp>::set_exception(exception_ptr __p) { 1147*700637cbSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr"); 1148*700637cbSDimitry Andric if (__state_ == nullptr) 1149*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1150*700637cbSDimitry Andric __state_->set_exception(__p); 1151*700637cbSDimitry Andric} 1152*700637cbSDimitry Andric 1153*700637cbSDimitry Andrictemplate <class _Rp> 1154*700637cbSDimitry Andricvoid promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) { 1155*700637cbSDimitry Andric if (__state_ == nullptr) 1156*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1157*700637cbSDimitry Andric __state_->set_value_at_thread_exit(__r); 1158*700637cbSDimitry Andric} 1159*700637cbSDimitry Andric 1160*700637cbSDimitry Andrictemplate <class _Rp> 1161*700637cbSDimitry Andricvoid promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) { 1162*700637cbSDimitry Andric if (__state_ == nullptr) 1163*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1164*700637cbSDimitry Andric __state_->set_value_at_thread_exit(std::move(__r)); 1165*700637cbSDimitry Andric} 1166*700637cbSDimitry Andric 1167*700637cbSDimitry Andrictemplate <class _Rp> 1168*700637cbSDimitry Andricvoid promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) { 1169*700637cbSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr"); 1170*700637cbSDimitry Andric if (__state_ == nullptr) 1171*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1172*700637cbSDimitry Andric __state_->set_exception_at_thread_exit(__p); 1173*700637cbSDimitry Andric} 1174*700637cbSDimitry Andric 1175*700637cbSDimitry Andric// promise<R&> 1176*700637cbSDimitry Andric 1177*700637cbSDimitry Andrictemplate <class _Rp> 1178*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise<_Rp&> { 1179*700637cbSDimitry Andric __assoc_state<_Rp&>* __state_; 1180*700637cbSDimitry Andric 1181*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1182*700637cbSDimitry Andric 1183*700637cbSDimitry Andric template <class> 1184*700637cbSDimitry Andric friend class packaged_task; 1185*700637cbSDimitry Andric 1186*700637cbSDimitry Andricpublic: 1187*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI promise(); 1188*700637cbSDimitry Andric template <class _Allocator> 1189*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a); 1190*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } 1191*700637cbSDimitry Andric promise(const promise& __rhs) = delete; 1192*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~promise(); 1193*700637cbSDimitry Andric 1194*700637cbSDimitry Andric // assignment 1195*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT { 1196*700637cbSDimitry Andric promise(std::move(__rhs)).swap(*this); 1197*700637cbSDimitry Andric return *this; 1198*700637cbSDimitry Andric } 1199*700637cbSDimitry Andric promise& operator=(const promise& __rhs) = delete; 1200*700637cbSDimitry Andric 1201*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } 1202*700637cbSDimitry Andric 1203*700637cbSDimitry Andric // retrieving the result 1204*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future(); 1205*700637cbSDimitry Andric 1206*700637cbSDimitry Andric // setting the result 1207*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r); 1208*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p); 1209*700637cbSDimitry Andric 1210*700637cbSDimitry Andric // setting the result with deferred notification 1211*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&); 1212*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p); 1213*700637cbSDimitry Andric}; 1214*700637cbSDimitry Andric 1215*700637cbSDimitry Andrictemplate <class _Rp> 1216*700637cbSDimitry Andricpromise<_Rp&>::promise() : __state_(new __assoc_state<_Rp&>) {} 1217*700637cbSDimitry Andric 1218*700637cbSDimitry Andrictemplate <class _Rp> 1219*700637cbSDimitry Andrictemplate <class _Alloc> 1220*700637cbSDimitry Andricpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) { 1221*700637cbSDimitry Andric typedef __assoc_state_alloc<_Rp&, _Alloc> _State; 1222*700637cbSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; 1223*700637cbSDimitry Andric typedef __allocator_destructor<_A2> _D2; 1224*700637cbSDimitry Andric _A2 __a(__a0); 1225*700637cbSDimitry Andric unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1226*700637cbSDimitry Andric ::new ((void*)std::addressof(*__hold.get())) _State(__a0); 1227*700637cbSDimitry Andric __state_ = std::addressof(*__hold.release()); 1228*700637cbSDimitry Andric} 1229*700637cbSDimitry Andric 1230*700637cbSDimitry Andrictemplate <class _Rp> 1231*700637cbSDimitry Andricpromise<_Rp&>::~promise() { 1232*700637cbSDimitry Andric if (__state_) { 1233*700637cbSDimitry Andric if (!__state_->__has_value() && __state_->use_count() > 1) 1234*700637cbSDimitry Andric __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise)))); 1235*700637cbSDimitry Andric __state_->__release_shared(); 1236*700637cbSDimitry Andric } 1237*700637cbSDimitry Andric} 1238*700637cbSDimitry Andric 1239*700637cbSDimitry Andrictemplate <class _Rp> 1240*700637cbSDimitry Andricfuture<_Rp&> promise<_Rp&>::get_future() { 1241*700637cbSDimitry Andric if (__state_ == nullptr) 1242*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1243*700637cbSDimitry Andric return future<_Rp&>(__state_); 1244*700637cbSDimitry Andric} 1245*700637cbSDimitry Andric 1246*700637cbSDimitry Andrictemplate <class _Rp> 1247*700637cbSDimitry Andricvoid promise<_Rp&>::set_value(_Rp& __r) { 1248*700637cbSDimitry Andric if (__state_ == nullptr) 1249*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1250*700637cbSDimitry Andric __state_->set_value(__r); 1251*700637cbSDimitry Andric} 1252*700637cbSDimitry Andric 1253*700637cbSDimitry Andrictemplate <class _Rp> 1254*700637cbSDimitry Andricvoid promise<_Rp&>::set_exception(exception_ptr __p) { 1255*700637cbSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr"); 1256*700637cbSDimitry Andric if (__state_ == nullptr) 1257*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1258*700637cbSDimitry Andric __state_->set_exception(__p); 1259*700637cbSDimitry Andric} 1260*700637cbSDimitry Andric 1261*700637cbSDimitry Andrictemplate <class _Rp> 1262*700637cbSDimitry Andricvoid promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) { 1263*700637cbSDimitry Andric if (__state_ == nullptr) 1264*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1265*700637cbSDimitry Andric __state_->set_value_at_thread_exit(__r); 1266*700637cbSDimitry Andric} 1267*700637cbSDimitry Andric 1268*700637cbSDimitry Andrictemplate <class _Rp> 1269*700637cbSDimitry Andricvoid promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) { 1270*700637cbSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr"); 1271*700637cbSDimitry Andric if (__state_ == nullptr) 1272*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1273*700637cbSDimitry Andric __state_->set_exception_at_thread_exit(__p); 1274*700637cbSDimitry Andric} 1275*700637cbSDimitry Andric 1276*700637cbSDimitry Andric// promise<void> 1277*700637cbSDimitry Andric 1278*700637cbSDimitry Andrictemplate <> 1279*700637cbSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI promise<void> { 1280*700637cbSDimitry Andric __assoc_sub_state* __state_; 1281*700637cbSDimitry Andric 1282*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1283*700637cbSDimitry Andric 1284*700637cbSDimitry Andric template <class> 1285*700637cbSDimitry Andric friend class packaged_task; 1286*700637cbSDimitry Andric 1287*700637cbSDimitry Andricpublic: 1288*700637cbSDimitry Andric promise(); 1289*700637cbSDimitry Andric template <class _Allocator> 1290*700637cbSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS promise(allocator_arg_t, const _Allocator& __a); 1291*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } 1292*700637cbSDimitry Andric promise(const promise& __rhs) = delete; 1293*700637cbSDimitry Andric ~promise(); 1294*700637cbSDimitry Andric 1295*700637cbSDimitry Andric // assignment 1296*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT { 1297*700637cbSDimitry Andric promise(std::move(__rhs)).swap(*this); 1298*700637cbSDimitry Andric return *this; 1299*700637cbSDimitry Andric } 1300*700637cbSDimitry Andric promise& operator=(const promise& __rhs) = delete; 1301*700637cbSDimitry Andric 1302*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } 1303*700637cbSDimitry Andric 1304*700637cbSDimitry Andric // retrieving the result 1305*700637cbSDimitry Andric future<void> get_future(); 1306*700637cbSDimitry Andric 1307*700637cbSDimitry Andric // setting the result 1308*700637cbSDimitry Andric void set_value(); 1309*700637cbSDimitry Andric void set_exception(exception_ptr __p); 1310*700637cbSDimitry Andric 1311*700637cbSDimitry Andric // setting the result with deferred notification 1312*700637cbSDimitry Andric void set_value_at_thread_exit(); 1313*700637cbSDimitry Andric void set_exception_at_thread_exit(exception_ptr __p); 1314*700637cbSDimitry Andric}; 1315*700637cbSDimitry Andric 1316*700637cbSDimitry Andrictemplate <class _Alloc> 1317*700637cbSDimitry Andricpromise<void>::promise(allocator_arg_t, const _Alloc& __a0) { 1318*700637cbSDimitry Andric typedef __assoc_sub_state_alloc<_Alloc> _State; 1319*700637cbSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; 1320*700637cbSDimitry Andric typedef __allocator_destructor<_A2> _D2; 1321*700637cbSDimitry Andric _A2 __a(__a0); 1322*700637cbSDimitry Andric unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1323*700637cbSDimitry Andric ::new ((void*)std::addressof(*__hold.get())) _State(__a0); 1324*700637cbSDimitry Andric __state_ = std::addressof(*__hold.release()); 1325*700637cbSDimitry Andric} 1326*700637cbSDimitry Andric 1327*700637cbSDimitry Andrictemplate <class _Rp> 1328*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT { 1329*700637cbSDimitry Andric __x.swap(__y); 1330*700637cbSDimitry Andric} 1331*700637cbSDimitry Andric 1332*700637cbSDimitry Andrictemplate <class _Rp, class _Alloc> 1333*700637cbSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc> : public true_type {}; 1334*700637cbSDimitry Andric 1335*700637cbSDimitry Andric// packaged_task 1336*700637cbSDimitry Andric 1337*700637cbSDimitry Andrictemplate <class _Fp> 1338*700637cbSDimitry Andricclass __packaged_task_base; 1339*700637cbSDimitry Andric 1340*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1341*700637cbSDimitry Andricclass __packaged_task_base<_Rp(_ArgTypes...)> { 1342*700637cbSDimitry Andricpublic: 1343*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __packaged_task_base() {} 1344*700637cbSDimitry Andric __packaged_task_base(const __packaged_task_base&) = delete; 1345*700637cbSDimitry Andric __packaged_task_base& operator=(const __packaged_task_base&) = delete; 1346*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL 1347*700637cbSDimitry Andric virtual ~__packaged_task_base() {} 1348*700637cbSDimitry Andric virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0; 1349*700637cbSDimitry Andric virtual void destroy() = 0; 1350*700637cbSDimitry Andric virtual void destroy_deallocate() = 0; 1351*700637cbSDimitry Andric virtual _Rp operator()(_ArgTypes&&...) = 0; 1352*700637cbSDimitry Andric}; 1353*700637cbSDimitry Andric 1354*700637cbSDimitry Andrictemplate <class _FD, class _Alloc, class _FB> 1355*700637cbSDimitry Andricclass __packaged_task_func; 1356*700637cbSDimitry Andric 1357*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 1358*700637cbSDimitry Andricclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __packaged_task_base<_Rp(_ArgTypes...)> { 1359*700637cbSDimitry Andric __compressed_pair<_Fp, _Alloc> __f_; 1360*700637cbSDimitry Andric 1361*700637cbSDimitry Andricpublic: 1362*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {} 1363*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(_Fp&& __f) : __f_(std::move(__f), __default_init_tag()) {} 1364*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __packaged_task_func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {} 1365*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __packaged_task_func(_Fp&& __f, const _Alloc& __a) : __f_(std::move(__f), __a) {} 1366*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; 1367*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy(); 1368*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate(); 1369*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __args); 1370*700637cbSDimitry Andric}; 1371*700637cbSDimitry Andric 1372*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 1373*700637cbSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to( 1374*700637cbSDimitry Andric __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT { 1375*700637cbSDimitry Andric ::new ((void*)__p) __packaged_task_func(std::move(__f_.first()), std::move(__f_.second())); 1376*700637cbSDimitry Andric} 1377*700637cbSDimitry Andric 1378*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 1379*700637cbSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() { 1380*700637cbSDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1381*700637cbSDimitry Andric} 1382*700637cbSDimitry Andric 1383*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 1384*700637cbSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() { 1385*700637cbSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap; 1386*700637cbSDimitry Andric typedef allocator_traits<_Ap> _ATraits; 1387*700637cbSDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 1388*700637cbSDimitry Andric _Ap __a(__f_.second()); 1389*700637cbSDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1390*700637cbSDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 1391*700637cbSDimitry Andric} 1392*700637cbSDimitry Andric 1393*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 1394*700637cbSDimitry Andric_Rp __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) { 1395*700637cbSDimitry Andric return std::__invoke(__f_.first(), std::forward<_ArgTypes>(__arg)...); 1396*700637cbSDimitry Andric} 1397*700637cbSDimitry Andric 1398*700637cbSDimitry Andrictemplate <class _Callable> 1399*700637cbSDimitry Andricclass __packaged_task_function; 1400*700637cbSDimitry Andric 1401*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1402*700637cbSDimitry Andricclass __packaged_task_function<_Rp(_ArgTypes...)> { 1403*700637cbSDimitry Andric typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; 1404*700637cbSDimitry Andric 1405*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __base* __get_buf() { return (__base*)&__buf_; } 1406*700637cbSDimitry Andric 1407*700637cbSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 1408*700637cbSDimitry Andric typename aligned_storage<3 * sizeof(void*)>::type __buf_; 1409*700637cbSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 1410*700637cbSDimitry Andric __base* __f_; 1411*700637cbSDimitry Andric 1412*700637cbSDimitry Andricpublic: 1413*700637cbSDimitry Andric typedef _Rp result_type; 1414*700637cbSDimitry Andric 1415*700637cbSDimitry Andric // construct/copy/destroy: 1416*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __packaged_task_function() _NOEXCEPT : __f_(nullptr) {} 1417*700637cbSDimitry Andric template <class _Fp> 1418*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f); 1419*700637cbSDimitry Andric template <class _Fp, class _Alloc> 1420*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); 1421*700637cbSDimitry Andric 1422*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; 1423*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; 1424*700637cbSDimitry Andric 1425*700637cbSDimitry Andric __packaged_task_function(const __packaged_task_function&) = delete; 1426*700637cbSDimitry Andric __packaged_task_function& operator=(const __packaged_task_function&) = delete; 1427*700637cbSDimitry Andric 1428*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function(); 1429*700637cbSDimitry Andric 1430*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT; 1431*700637cbSDimitry Andric 1432*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; 1433*700637cbSDimitry Andric}; 1434*700637cbSDimitry Andric 1435*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1436*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT { 1437*700637cbSDimitry Andric if (__f.__f_ == nullptr) 1438*700637cbSDimitry Andric __f_ = nullptr; 1439*700637cbSDimitry Andric else if (__f.__f_ == __f.__get_buf()) { 1440*700637cbSDimitry Andric __f.__f_->__move_to(__get_buf()); 1441*700637cbSDimitry Andric __f_ = (__base*)&__buf_; 1442*700637cbSDimitry Andric } else { 1443*700637cbSDimitry Andric __f_ = __f.__f_; 1444*700637cbSDimitry Andric __f.__f_ = nullptr; 1445*700637cbSDimitry Andric } 1446*700637cbSDimitry Andric} 1447*700637cbSDimitry Andric 1448*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1449*700637cbSDimitry Andrictemplate <class _Fp> 1450*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) : __f_(nullptr) { 1451*700637cbSDimitry Andric typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR; 1452*700637cbSDimitry Andric typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; 1453*700637cbSDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) { 1454*700637cbSDimitry Andric ::new ((void*)&__buf_) _FF(std::forward<_Fp>(__f)); 1455*700637cbSDimitry Andric __f_ = (__base*)&__buf_; 1456*700637cbSDimitry Andric } else { 1457*700637cbSDimitry Andric typedef allocator<_FF> _Ap; 1458*700637cbSDimitry Andric _Ap __a; 1459*700637cbSDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 1460*700637cbSDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1461*700637cbSDimitry Andric ::new ((void*)__hold.get()) _FF(std::forward<_Fp>(__f), allocator<_FR>(__a)); 1462*700637cbSDimitry Andric __f_ = __hold.release(); 1463*700637cbSDimitry Andric } 1464*700637cbSDimitry Andric} 1465*700637cbSDimitry Andric 1466*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1467*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc> 1468*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_arg_t, const _Alloc& __a0, _Fp&& __f) 1469*700637cbSDimitry Andric : __f_(nullptr) { 1470*700637cbSDimitry Andric typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR; 1471*700637cbSDimitry Andric typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; 1472*700637cbSDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) { 1473*700637cbSDimitry Andric __f_ = (__base*)&__buf_; 1474*700637cbSDimitry Andric ::new ((void*)__f_) _FF(std::forward<_Fp>(__f)); 1475*700637cbSDimitry Andric } else { 1476*700637cbSDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap; 1477*700637cbSDimitry Andric _Ap __a(__a0); 1478*700637cbSDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 1479*700637cbSDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1480*700637cbSDimitry Andric ::new ((void*)std::addressof(*__hold.get())) _FF(std::forward<_Fp>(__f), _Alloc(__a)); 1481*700637cbSDimitry Andric __f_ = std::addressof(*__hold.release()); 1482*700637cbSDimitry Andric } 1483*700637cbSDimitry Andric} 1484*700637cbSDimitry Andric 1485*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1486*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>& 1487*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT { 1488*700637cbSDimitry Andric if (__f_ == __get_buf()) 1489*700637cbSDimitry Andric __f_->destroy(); 1490*700637cbSDimitry Andric else if (__f_) 1491*700637cbSDimitry Andric __f_->destroy_deallocate(); 1492*700637cbSDimitry Andric __f_ = nullptr; 1493*700637cbSDimitry Andric if (__f.__f_ == nullptr) 1494*700637cbSDimitry Andric __f_ = nullptr; 1495*700637cbSDimitry Andric else if (__f.__f_ == __f.__get_buf()) { 1496*700637cbSDimitry Andric __f.__f_->__move_to(__get_buf()); 1497*700637cbSDimitry Andric __f_ = __get_buf(); 1498*700637cbSDimitry Andric } else { 1499*700637cbSDimitry Andric __f_ = __f.__f_; 1500*700637cbSDimitry Andric __f.__f_ = nullptr; 1501*700637cbSDimitry Andric } 1502*700637cbSDimitry Andric return *this; 1503*700637cbSDimitry Andric} 1504*700637cbSDimitry Andric 1505*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1506*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() { 1507*700637cbSDimitry Andric if (__f_ == __get_buf()) 1508*700637cbSDimitry Andric __f_->destroy(); 1509*700637cbSDimitry Andric else if (__f_) 1510*700637cbSDimitry Andric __f_->destroy_deallocate(); 1511*700637cbSDimitry Andric} 1512*700637cbSDimitry Andric 1513*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1514*700637cbSDimitry Andric_LIBCPP_NO_CFI void __packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT { 1515*700637cbSDimitry Andric if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { 1516*700637cbSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 1517*700637cbSDimitry Andric typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 1518*700637cbSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 1519*700637cbSDimitry Andric __base* __t = (__base*)&__tempbuf; 1520*700637cbSDimitry Andric __f_->__move_to(__t); 1521*700637cbSDimitry Andric __f_->destroy(); 1522*700637cbSDimitry Andric __f_ = nullptr; 1523*700637cbSDimitry Andric __f.__f_->__move_to((__base*)&__buf_); 1524*700637cbSDimitry Andric __f.__f_->destroy(); 1525*700637cbSDimitry Andric __f.__f_ = nullptr; 1526*700637cbSDimitry Andric __f_ = (__base*)&__buf_; 1527*700637cbSDimitry Andric __t->__move_to((__base*)&__f.__buf_); 1528*700637cbSDimitry Andric __t->destroy(); 1529*700637cbSDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 1530*700637cbSDimitry Andric } else if (__f_ == (__base*)&__buf_) { 1531*700637cbSDimitry Andric __f_->__move_to((__base*)&__f.__buf_); 1532*700637cbSDimitry Andric __f_->destroy(); 1533*700637cbSDimitry Andric __f_ = __f.__f_; 1534*700637cbSDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 1535*700637cbSDimitry Andric } else if (__f.__f_ == (__base*)&__f.__buf_) { 1536*700637cbSDimitry Andric __f.__f_->__move_to((__base*)&__buf_); 1537*700637cbSDimitry Andric __f.__f_->destroy(); 1538*700637cbSDimitry Andric __f.__f_ = __f_; 1539*700637cbSDimitry Andric __f_ = (__base*)&__buf_; 1540*700637cbSDimitry Andric } else 1541*700637cbSDimitry Andric std::swap(__f_, __f.__f_); 1542*700637cbSDimitry Andric} 1543*700637cbSDimitry Andric 1544*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1545*700637cbSDimitry Andricinline _Rp __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { 1546*700637cbSDimitry Andric return (*__f_)(std::forward<_ArgTypes>(__arg)...); 1547*700637cbSDimitry Andric} 1548*700637cbSDimitry Andric 1549*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1550*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<_Rp(_ArgTypes...)> { 1551*700637cbSDimitry Andricpublic: 1552*700637cbSDimitry Andric typedef _Rp result_type; // extension 1553*700637cbSDimitry Andric 1554*700637cbSDimitry Andricprivate: 1555*700637cbSDimitry Andric __packaged_task_function<result_type(_ArgTypes...)> __f_; 1556*700637cbSDimitry Andric promise<result_type> __p_; 1557*700637cbSDimitry Andric 1558*700637cbSDimitry Andricpublic: 1559*700637cbSDimitry Andric // construction and destruction 1560*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {} 1561*700637cbSDimitry Andric 1562*700637cbSDimitry Andric template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0> 1563*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {} 1564*700637cbSDimitry Andric 1565*700637cbSDimitry Andric template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0> 1566*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 1567*700637cbSDimitry Andric : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {} 1568*700637cbSDimitry Andric // ~packaged_task() = default; 1569*700637cbSDimitry Andric 1570*700637cbSDimitry Andric // no copy 1571*700637cbSDimitry Andric packaged_task(const packaged_task&) = delete; 1572*700637cbSDimitry Andric packaged_task& operator=(const packaged_task&) = delete; 1573*700637cbSDimitry Andric 1574*700637cbSDimitry Andric // move support 1575*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT 1576*700637cbSDimitry Andric : __f_(std::move(__other.__f_)), 1577*700637cbSDimitry Andric __p_(std::move(__other.__p_)) {} 1578*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT { 1579*700637cbSDimitry Andric __f_ = std::move(__other.__f_); 1580*700637cbSDimitry Andric __p_ = std::move(__other.__p_); 1581*700637cbSDimitry Andric return *this; 1582*700637cbSDimitry Andric } 1583*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT { 1584*700637cbSDimitry Andric __f_.swap(__other.__f_); 1585*700637cbSDimitry Andric __p_.swap(__other.__p_); 1586*700637cbSDimitry Andric } 1587*700637cbSDimitry Andric 1588*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; } 1589*700637cbSDimitry Andric 1590*700637cbSDimitry Andric // result retrieval 1591*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); } 1592*700637cbSDimitry Andric 1593*700637cbSDimitry Andric // execution 1594*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args); 1595*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args); 1596*700637cbSDimitry Andric 1597*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void reset(); 1598*700637cbSDimitry Andric}; 1599*700637cbSDimitry Andric 1600*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1601*700637cbSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) { 1602*700637cbSDimitry Andric if (__p_.__state_ == nullptr) 1603*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1604*700637cbSDimitry Andric if (__p_.__state_->__has_value()) 1605*700637cbSDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 1606*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1607*700637cbSDimitry Andric try { 1608*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 1609*700637cbSDimitry Andric __p_.set_value(__f_(std::forward<_ArgTypes>(__args)...)); 1610*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1611*700637cbSDimitry Andric } catch (...) { 1612*700637cbSDimitry Andric __p_.set_exception(current_exception()); 1613*700637cbSDimitry Andric } 1614*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 1615*700637cbSDimitry Andric} 1616*700637cbSDimitry Andric 1617*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1618*700637cbSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) { 1619*700637cbSDimitry Andric if (__p_.__state_ == nullptr) 1620*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1621*700637cbSDimitry Andric if (__p_.__state_->__has_value()) 1622*700637cbSDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 1623*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1624*700637cbSDimitry Andric try { 1625*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 1626*700637cbSDimitry Andric __p_.set_value_at_thread_exit(__f_(std::forward<_ArgTypes>(__args)...)); 1627*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1628*700637cbSDimitry Andric } catch (...) { 1629*700637cbSDimitry Andric __p_.set_exception_at_thread_exit(current_exception()); 1630*700637cbSDimitry Andric } 1631*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 1632*700637cbSDimitry Andric} 1633*700637cbSDimitry Andric 1634*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1635*700637cbSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::reset() { 1636*700637cbSDimitry Andric if (!valid()) 1637*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1638*700637cbSDimitry Andric __p_ = promise<result_type>(); 1639*700637cbSDimitry Andric} 1640*700637cbSDimitry Andric 1641*700637cbSDimitry Andrictemplate <class... _ArgTypes> 1642*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<void(_ArgTypes...)> { 1643*700637cbSDimitry Andricpublic: 1644*700637cbSDimitry Andric typedef void result_type; // extension 1645*700637cbSDimitry Andric 1646*700637cbSDimitry Andricprivate: 1647*700637cbSDimitry Andric __packaged_task_function<result_type(_ArgTypes...)> __f_; 1648*700637cbSDimitry Andric promise<result_type> __p_; 1649*700637cbSDimitry Andric 1650*700637cbSDimitry Andricpublic: 1651*700637cbSDimitry Andric // construction and destruction 1652*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {} 1653*700637cbSDimitry Andric template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0> 1654*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {} 1655*700637cbSDimitry Andric template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0> 1656*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 1657*700637cbSDimitry Andric : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {} 1658*700637cbSDimitry Andric // ~packaged_task() = default; 1659*700637cbSDimitry Andric 1660*700637cbSDimitry Andric // no copy 1661*700637cbSDimitry Andric packaged_task(const packaged_task&) = delete; 1662*700637cbSDimitry Andric packaged_task& operator=(const packaged_task&) = delete; 1663*700637cbSDimitry Andric 1664*700637cbSDimitry Andric // move support 1665*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT 1666*700637cbSDimitry Andric : __f_(std::move(__other.__f_)), 1667*700637cbSDimitry Andric __p_(std::move(__other.__p_)) {} 1668*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT { 1669*700637cbSDimitry Andric __f_ = std::move(__other.__f_); 1670*700637cbSDimitry Andric __p_ = std::move(__other.__p_); 1671*700637cbSDimitry Andric return *this; 1672*700637cbSDimitry Andric } 1673*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT { 1674*700637cbSDimitry Andric __f_.swap(__other.__f_); 1675*700637cbSDimitry Andric __p_.swap(__other.__p_); 1676*700637cbSDimitry Andric } 1677*700637cbSDimitry Andric 1678*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; } 1679*700637cbSDimitry Andric 1680*700637cbSDimitry Andric // result retrieval 1681*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); } 1682*700637cbSDimitry Andric 1683*700637cbSDimitry Andric // execution 1684*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args); 1685*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args); 1686*700637cbSDimitry Andric 1687*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void reset(); 1688*700637cbSDimitry Andric}; 1689*700637cbSDimitry Andric 1690*700637cbSDimitry Andrictemplate <class... _ArgTypes> 1691*700637cbSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) { 1692*700637cbSDimitry Andric if (__p_.__state_ == nullptr) 1693*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1694*700637cbSDimitry Andric if (__p_.__state_->__has_value()) 1695*700637cbSDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 1696*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1697*700637cbSDimitry Andric try { 1698*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 1699*700637cbSDimitry Andric __f_(std::forward<_ArgTypes>(__args)...); 1700*700637cbSDimitry Andric __p_.set_value(); 1701*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1702*700637cbSDimitry Andric } catch (...) { 1703*700637cbSDimitry Andric __p_.set_exception(current_exception()); 1704*700637cbSDimitry Andric } 1705*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 1706*700637cbSDimitry Andric} 1707*700637cbSDimitry Andric 1708*700637cbSDimitry Andrictemplate <class... _ArgTypes> 1709*700637cbSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) { 1710*700637cbSDimitry Andric if (__p_.__state_ == nullptr) 1711*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1712*700637cbSDimitry Andric if (__p_.__state_->__has_value()) 1713*700637cbSDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 1714*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1715*700637cbSDimitry Andric try { 1716*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 1717*700637cbSDimitry Andric __f_(std::forward<_ArgTypes>(__args)...); 1718*700637cbSDimitry Andric __p_.set_value_at_thread_exit(); 1719*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1720*700637cbSDimitry Andric } catch (...) { 1721*700637cbSDimitry Andric __p_.set_exception_at_thread_exit(current_exception()); 1722*700637cbSDimitry Andric } 1723*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 1724*700637cbSDimitry Andric} 1725*700637cbSDimitry Andric 1726*700637cbSDimitry Andrictemplate <class... _ArgTypes> 1727*700637cbSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::reset() { 1728*700637cbSDimitry Andric if (!valid()) 1729*700637cbSDimitry Andric __throw_future_error(future_errc::no_state); 1730*700637cbSDimitry Andric __p_ = promise<result_type>(); 1731*700637cbSDimitry Andric} 1732*700637cbSDimitry Andric 1733*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes> 1734*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void 1735*700637cbSDimitry Andricswap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT { 1736*700637cbSDimitry Andric __x.swap(__y); 1737*700637cbSDimitry Andric} 1738*700637cbSDimitry Andric 1739*700637cbSDimitry Andrictemplate <class _Callable, class _Alloc> 1740*700637cbSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {}; 1741*700637cbSDimitry Andric 1742*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 1743*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f) { 1744*700637cbSDimitry Andric unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> __h( 1745*700637cbSDimitry Andric new __deferred_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f))); 1746*700637cbSDimitry Andric return future<_Rp>(__h.get()); 1747*700637cbSDimitry Andric} 1748*700637cbSDimitry Andric 1749*700637cbSDimitry Andrictemplate <class _Rp, class _Fp> 1750*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f) { 1751*700637cbSDimitry Andric unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> __h( 1752*700637cbSDimitry Andric new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f))); 1753*700637cbSDimitry Andric std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach(); 1754*700637cbSDimitry Andric return future<_Rp>(__h.get()); 1755*700637cbSDimitry Andric} 1756*700637cbSDimitry Andric 1757*700637cbSDimitry Andric// shared_future 1758*700637cbSDimitry Andric 1759*700637cbSDimitry Andrictemplate <class _Rp> 1760*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future { 1761*700637cbSDimitry Andric __assoc_state<_Rp>* __state_; 1762*700637cbSDimitry Andric 1763*700637cbSDimitry Andricpublic: 1764*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {} 1765*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { 1766*700637cbSDimitry Andric if (__state_) 1767*700637cbSDimitry Andric __state_->__add_shared(); 1768*700637cbSDimitry Andric } 1769*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; } 1770*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { 1771*700637cbSDimitry Andric __rhs.__state_ = nullptr; 1772*700637cbSDimitry Andric } 1773*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~shared_future(); 1774*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT; 1775*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT { 1776*700637cbSDimitry Andric shared_future(std::move(__rhs)).swap(*this); 1777*700637cbSDimitry Andric return *this; 1778*700637cbSDimitry Andric } 1779*700637cbSDimitry Andric 1780*700637cbSDimitry Andric // retrieving the value 1781*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Rp& get() const { return __state_->copy(); } 1782*700637cbSDimitry Andric 1783*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } 1784*700637cbSDimitry Andric 1785*700637cbSDimitry Andric // functions to check state 1786*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } 1787*700637cbSDimitry Andric 1788*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } 1789*700637cbSDimitry Andric template <class _Rep, class _Period> 1790*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { 1791*700637cbSDimitry Andric return __state_->wait_for(__rel_time); 1792*700637cbSDimitry Andric } 1793*700637cbSDimitry Andric template <class _Clock, class _Duration> 1794*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { 1795*700637cbSDimitry Andric return __state_->wait_until(__abs_time); 1796*700637cbSDimitry Andric } 1797*700637cbSDimitry Andric}; 1798*700637cbSDimitry Andric 1799*700637cbSDimitry Andrictemplate <class _Rp> 1800*700637cbSDimitry Andricshared_future<_Rp>::~shared_future() { 1801*700637cbSDimitry Andric if (__state_) 1802*700637cbSDimitry Andric __state_->__release_shared(); 1803*700637cbSDimitry Andric} 1804*700637cbSDimitry Andric 1805*700637cbSDimitry Andrictemplate <class _Rp> 1806*700637cbSDimitry Andricshared_future<_Rp>& shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT { 1807*700637cbSDimitry Andric if (__rhs.__state_) 1808*700637cbSDimitry Andric __rhs.__state_->__add_shared(); 1809*700637cbSDimitry Andric if (__state_) 1810*700637cbSDimitry Andric __state_->__release_shared(); 1811*700637cbSDimitry Andric __state_ = __rhs.__state_; 1812*700637cbSDimitry Andric return *this; 1813*700637cbSDimitry Andric} 1814*700637cbSDimitry Andric 1815*700637cbSDimitry Andrictemplate <class _Rp> 1816*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&> { 1817*700637cbSDimitry Andric __assoc_state<_Rp&>* __state_; 1818*700637cbSDimitry Andric 1819*700637cbSDimitry Andricpublic: 1820*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {} 1821*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) { 1822*700637cbSDimitry Andric if (__state_) 1823*700637cbSDimitry Andric __state_->__add_shared(); 1824*700637cbSDimitry Andric } 1825*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; } 1826*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { 1827*700637cbSDimitry Andric __rhs.__state_ = nullptr; 1828*700637cbSDimitry Andric } 1829*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~shared_future(); 1830*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs); 1831*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT { 1832*700637cbSDimitry Andric shared_future(std::move(__rhs)).swap(*this); 1833*700637cbSDimitry Andric return *this; 1834*700637cbSDimitry Andric } 1835*700637cbSDimitry Andric 1836*700637cbSDimitry Andric // retrieving the value 1837*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp& get() const { return __state_->copy(); } 1838*700637cbSDimitry Andric 1839*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } 1840*700637cbSDimitry Andric 1841*700637cbSDimitry Andric // functions to check state 1842*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } 1843*700637cbSDimitry Andric 1844*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } 1845*700637cbSDimitry Andric template <class _Rep, class _Period> 1846*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { 1847*700637cbSDimitry Andric return __state_->wait_for(__rel_time); 1848*700637cbSDimitry Andric } 1849*700637cbSDimitry Andric template <class _Clock, class _Duration> 1850*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { 1851*700637cbSDimitry Andric return __state_->wait_until(__abs_time); 1852*700637cbSDimitry Andric } 1853*700637cbSDimitry Andric}; 1854*700637cbSDimitry Andric 1855*700637cbSDimitry Andrictemplate <class _Rp> 1856*700637cbSDimitry Andricshared_future<_Rp&>::~shared_future() { 1857*700637cbSDimitry Andric if (__state_) 1858*700637cbSDimitry Andric __state_->__release_shared(); 1859*700637cbSDimitry Andric} 1860*700637cbSDimitry Andric 1861*700637cbSDimitry Andrictemplate <class _Rp> 1862*700637cbSDimitry Andricshared_future<_Rp&>& shared_future<_Rp&>::operator=(const shared_future& __rhs) { 1863*700637cbSDimitry Andric if (__rhs.__state_) 1864*700637cbSDimitry Andric __rhs.__state_->__add_shared(); 1865*700637cbSDimitry Andric if (__state_) 1866*700637cbSDimitry Andric __state_->__release_shared(); 1867*700637cbSDimitry Andric __state_ = __rhs.__state_; 1868*700637cbSDimitry Andric return *this; 1869*700637cbSDimitry Andric} 1870*700637cbSDimitry Andric 1871*700637cbSDimitry Andrictemplate <> 1872*700637cbSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI shared_future<void> { 1873*700637cbSDimitry Andric __assoc_sub_state* __state_; 1874*700637cbSDimitry Andric 1875*700637cbSDimitry Andricpublic: 1876*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {} 1877*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) { 1878*700637cbSDimitry Andric if (__state_) 1879*700637cbSDimitry Andric __state_->__add_shared(); 1880*700637cbSDimitry Andric } 1881*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; } 1882*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { 1883*700637cbSDimitry Andric __rhs.__state_ = nullptr; 1884*700637cbSDimitry Andric } 1885*700637cbSDimitry Andric ~shared_future(); 1886*700637cbSDimitry Andric shared_future& operator=(const shared_future& __rhs); 1887*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT { 1888*700637cbSDimitry Andric shared_future(std::move(__rhs)).swap(*this); 1889*700637cbSDimitry Andric return *this; 1890*700637cbSDimitry Andric } 1891*700637cbSDimitry Andric 1892*700637cbSDimitry Andric // retrieving the value 1893*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void get() const { __state_->copy(); } 1894*700637cbSDimitry Andric 1895*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } 1896*700637cbSDimitry Andric 1897*700637cbSDimitry Andric // functions to check state 1898*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } 1899*700637cbSDimitry Andric 1900*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } 1901*700637cbSDimitry Andric template <class _Rep, class _Period> 1902*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { 1903*700637cbSDimitry Andric return __state_->wait_for(__rel_time); 1904*700637cbSDimitry Andric } 1905*700637cbSDimitry Andric template <class _Clock, class _Duration> 1906*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { 1907*700637cbSDimitry Andric return __state_->wait_until(__abs_time); 1908*700637cbSDimitry Andric } 1909*700637cbSDimitry Andric}; 1910*700637cbSDimitry Andric 1911*700637cbSDimitry Andrictemplate <class _Rp> 1912*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT { 1913*700637cbSDimitry Andric __x.swap(__y); 1914*700637cbSDimitry Andric} 1915*700637cbSDimitry Andric 1916*700637cbSDimitry Andrictemplate <class _Rp> 1917*700637cbSDimitry Andricinline shared_future<_Rp> future<_Rp>::share() _NOEXCEPT { 1918*700637cbSDimitry Andric return shared_future<_Rp>(std::move(*this)); 1919*700637cbSDimitry Andric} 1920*700637cbSDimitry Andric 1921*700637cbSDimitry Andrictemplate <class _Rp> 1922*700637cbSDimitry Andricinline shared_future<_Rp&> future<_Rp&>::share() _NOEXCEPT { 1923*700637cbSDimitry Andric return shared_future<_Rp&>(std::move(*this)); 1924*700637cbSDimitry Andric} 1925*700637cbSDimitry Andric 1926*700637cbSDimitry Andricinline shared_future<void> future<void>::share() _NOEXCEPT { return shared_future<void>(std::move(*this)); } 1927*700637cbSDimitry Andric 1928*700637cbSDimitry Andric_LIBCPP_END_NAMESPACE_STD 1929*700637cbSDimitry Andric 1930*700637cbSDimitry Andric_LIBCPP_POP_MACROS 1931*700637cbSDimitry Andric 1932*700637cbSDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_THREADS) 1933*700637cbSDimitry Andric 1934*700637cbSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) 1935*700637cbSDimitry Andric# include <__cxx03/chrono> 1936*700637cbSDimitry Andric#endif 1937*700637cbSDimitry Andric 1938*700637cbSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) 1939*700637cbSDimitry Andric# include <__cxx03/atomic> 1940*700637cbSDimitry Andric# include <__cxx03/cstdlib> 1941*700637cbSDimitry Andric# include <__cxx03/exception> 1942*700637cbSDimitry Andric# include <__cxx03/iosfwd> 1943*700637cbSDimitry Andric# include <__cxx03/system_error> 1944*700637cbSDimitry Andric#endif 1945*700637cbSDimitry Andric 1946*700637cbSDimitry Andric#endif // _LIBCPP___CXX03_FUTURE 1947