1*0b57cec5SDimitry Andric// -*- C++ -*- 2*0b57cec5SDimitry Andric//===--------------------------- future -----------------------------------===// 3*0b57cec5SDimitry Andric// 4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*0b57cec5SDimitry Andric// 8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 9*0b57cec5SDimitry Andric 10*0b57cec5SDimitry Andric#ifndef _LIBCPP_FUTURE 11*0b57cec5SDimitry Andric#define _LIBCPP_FUTURE 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric/* 14*0b57cec5SDimitry Andric future synopsis 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andricnamespace std 17*0b57cec5SDimitry Andric{ 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andricenum class future_errc 20*0b57cec5SDimitry Andric{ 21*0b57cec5SDimitry Andric future_already_retrieved = 1, 22*0b57cec5SDimitry Andric promise_already_satisfied, 23*0b57cec5SDimitry Andric no_state, 24*0b57cec5SDimitry Andric broken_promise 25*0b57cec5SDimitry Andric}; 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andricenum class launch 28*0b57cec5SDimitry Andric{ 29*0b57cec5SDimitry Andric async = 1, 30*0b57cec5SDimitry Andric deferred = 2, 31*0b57cec5SDimitry Andric any = async | deferred 32*0b57cec5SDimitry Andric}; 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andricenum class future_status 35*0b57cec5SDimitry Andric{ 36*0b57cec5SDimitry Andric ready, 37*0b57cec5SDimitry Andric timeout, 38*0b57cec5SDimitry Andric deferred 39*0b57cec5SDimitry Andric}; 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andrictemplate <> struct is_error_code_enum<future_errc> : public true_type { }; 42*0b57cec5SDimitry Andricerror_code make_error_code(future_errc e) noexcept; 43*0b57cec5SDimitry Andricerror_condition make_error_condition(future_errc e) noexcept; 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andricconst error_category& future_category() noexcept; 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andricclass future_error 48*0b57cec5SDimitry Andric : public logic_error 49*0b57cec5SDimitry Andric{ 50*0b57cec5SDimitry Andricpublic: 51*0b57cec5SDimitry Andric future_error(error_code ec); // exposition only 52*0b57cec5SDimitry Andric explicit future_error(future_errc); // C++17 53*0b57cec5SDimitry Andric const error_code& code() const noexcept; 54*0b57cec5SDimitry Andric const char* what() const noexcept; 55*0b57cec5SDimitry Andric}; 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andrictemplate <class R> 58*0b57cec5SDimitry Andricclass promise 59*0b57cec5SDimitry Andric{ 60*0b57cec5SDimitry Andricpublic: 61*0b57cec5SDimitry Andric promise(); 62*0b57cec5SDimitry Andric template <class Allocator> 63*0b57cec5SDimitry Andric promise(allocator_arg_t, const Allocator& a); 64*0b57cec5SDimitry Andric promise(promise&& rhs) noexcept; 65*0b57cec5SDimitry Andric promise(const promise& rhs) = delete; 66*0b57cec5SDimitry Andric ~promise(); 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric // assignment 69*0b57cec5SDimitry Andric promise& operator=(promise&& rhs) noexcept; 70*0b57cec5SDimitry Andric promise& operator=(const promise& rhs) = delete; 71*0b57cec5SDimitry Andric void swap(promise& other) noexcept; 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric // retrieving the result 74*0b57cec5SDimitry Andric future<R> get_future(); 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andric // setting the result 77*0b57cec5SDimitry Andric void set_value(const R& r); 78*0b57cec5SDimitry Andric void set_value(R&& r); 79*0b57cec5SDimitry Andric void set_exception(exception_ptr p); 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric // setting the result with deferred notification 82*0b57cec5SDimitry Andric void set_value_at_thread_exit(const R& r); 83*0b57cec5SDimitry Andric void set_value_at_thread_exit(R&& r); 84*0b57cec5SDimitry Andric void set_exception_at_thread_exit(exception_ptr p); 85*0b57cec5SDimitry Andric}; 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andrictemplate <class R> 88*0b57cec5SDimitry Andricclass promise<R&> 89*0b57cec5SDimitry Andric{ 90*0b57cec5SDimitry Andricpublic: 91*0b57cec5SDimitry Andric promise(); 92*0b57cec5SDimitry Andric template <class Allocator> 93*0b57cec5SDimitry Andric promise(allocator_arg_t, const Allocator& a); 94*0b57cec5SDimitry Andric promise(promise&& rhs) noexcept; 95*0b57cec5SDimitry Andric promise(const promise& rhs) = delete; 96*0b57cec5SDimitry Andric ~promise(); 97*0b57cec5SDimitry Andric 98*0b57cec5SDimitry Andric // assignment 99*0b57cec5SDimitry Andric promise& operator=(promise&& rhs) noexcept; 100*0b57cec5SDimitry Andric promise& operator=(const promise& rhs) = delete; 101*0b57cec5SDimitry Andric void swap(promise& other) noexcept; 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric // retrieving the result 104*0b57cec5SDimitry Andric future<R&> get_future(); 105*0b57cec5SDimitry Andric 106*0b57cec5SDimitry Andric // setting the result 107*0b57cec5SDimitry Andric void set_value(R& r); 108*0b57cec5SDimitry Andric void set_exception(exception_ptr p); 109*0b57cec5SDimitry Andric 110*0b57cec5SDimitry Andric // setting the result with deferred notification 111*0b57cec5SDimitry Andric void set_value_at_thread_exit(R&); 112*0b57cec5SDimitry Andric void set_exception_at_thread_exit(exception_ptr p); 113*0b57cec5SDimitry Andric}; 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andrictemplate <> 116*0b57cec5SDimitry Andricclass promise<void> 117*0b57cec5SDimitry Andric{ 118*0b57cec5SDimitry Andricpublic: 119*0b57cec5SDimitry Andric promise(); 120*0b57cec5SDimitry Andric template <class Allocator> 121*0b57cec5SDimitry Andric promise(allocator_arg_t, const Allocator& a); 122*0b57cec5SDimitry Andric promise(promise&& rhs) noexcept; 123*0b57cec5SDimitry Andric promise(const promise& rhs) = delete; 124*0b57cec5SDimitry Andric ~promise(); 125*0b57cec5SDimitry Andric 126*0b57cec5SDimitry Andric // assignment 127*0b57cec5SDimitry Andric promise& operator=(promise&& rhs) noexcept; 128*0b57cec5SDimitry Andric promise& operator=(const promise& rhs) = delete; 129*0b57cec5SDimitry Andric void swap(promise& other) noexcept; 130*0b57cec5SDimitry Andric 131*0b57cec5SDimitry Andric // retrieving the result 132*0b57cec5SDimitry Andric future<void> get_future(); 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric // setting the result 135*0b57cec5SDimitry Andric void set_value(); 136*0b57cec5SDimitry Andric void set_exception(exception_ptr p); 137*0b57cec5SDimitry Andric 138*0b57cec5SDimitry Andric // setting the result with deferred notification 139*0b57cec5SDimitry Andric void set_value_at_thread_exit(); 140*0b57cec5SDimitry Andric void set_exception_at_thread_exit(exception_ptr p); 141*0b57cec5SDimitry Andric}; 142*0b57cec5SDimitry Andric 143*0b57cec5SDimitry Andrictemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept; 144*0b57cec5SDimitry Andric 145*0b57cec5SDimitry Andrictemplate <class R, class Alloc> 146*0b57cec5SDimitry Andric struct uses_allocator<promise<R>, Alloc> : public true_type {}; 147*0b57cec5SDimitry Andric 148*0b57cec5SDimitry Andrictemplate <class R> 149*0b57cec5SDimitry Andricclass future 150*0b57cec5SDimitry Andric{ 151*0b57cec5SDimitry Andricpublic: 152*0b57cec5SDimitry Andric future() noexcept; 153*0b57cec5SDimitry Andric future(future&&) noexcept; 154*0b57cec5SDimitry Andric future(const future& rhs) = delete; 155*0b57cec5SDimitry Andric ~future(); 156*0b57cec5SDimitry Andric future& operator=(const future& rhs) = delete; 157*0b57cec5SDimitry Andric future& operator=(future&&) noexcept; 158*0b57cec5SDimitry Andric shared_future<R> share() noexcept; 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric // retrieving the value 161*0b57cec5SDimitry Andric R get(); 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric // functions to check state 164*0b57cec5SDimitry Andric bool valid() const noexcept; 165*0b57cec5SDimitry Andric 166*0b57cec5SDimitry Andric void wait() const; 167*0b57cec5SDimitry Andric template <class Rep, class Period> 168*0b57cec5SDimitry Andric future_status 169*0b57cec5SDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 170*0b57cec5SDimitry Andric template <class Clock, class Duration> 171*0b57cec5SDimitry Andric future_status 172*0b57cec5SDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 173*0b57cec5SDimitry Andric}; 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andrictemplate <class R> 176*0b57cec5SDimitry Andricclass future<R&> 177*0b57cec5SDimitry Andric{ 178*0b57cec5SDimitry Andricpublic: 179*0b57cec5SDimitry Andric future() noexcept; 180*0b57cec5SDimitry Andric future(future&&) noexcept; 181*0b57cec5SDimitry Andric future(const future& rhs) = delete; 182*0b57cec5SDimitry Andric ~future(); 183*0b57cec5SDimitry Andric future& operator=(const future& rhs) = delete; 184*0b57cec5SDimitry Andric future& operator=(future&&) noexcept; 185*0b57cec5SDimitry Andric shared_future<R&> share() noexcept; 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric // retrieving the value 188*0b57cec5SDimitry Andric R& get(); 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric // functions to check state 191*0b57cec5SDimitry Andric bool valid() const noexcept; 192*0b57cec5SDimitry Andric 193*0b57cec5SDimitry Andric void wait() const; 194*0b57cec5SDimitry Andric template <class Rep, class Period> 195*0b57cec5SDimitry Andric future_status 196*0b57cec5SDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 197*0b57cec5SDimitry Andric template <class Clock, class Duration> 198*0b57cec5SDimitry Andric future_status 199*0b57cec5SDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 200*0b57cec5SDimitry Andric}; 201*0b57cec5SDimitry Andric 202*0b57cec5SDimitry Andrictemplate <> 203*0b57cec5SDimitry Andricclass future<void> 204*0b57cec5SDimitry Andric{ 205*0b57cec5SDimitry Andricpublic: 206*0b57cec5SDimitry Andric future() noexcept; 207*0b57cec5SDimitry Andric future(future&&) noexcept; 208*0b57cec5SDimitry Andric future(const future& rhs) = delete; 209*0b57cec5SDimitry Andric ~future(); 210*0b57cec5SDimitry Andric future& operator=(const future& rhs) = delete; 211*0b57cec5SDimitry Andric future& operator=(future&&) noexcept; 212*0b57cec5SDimitry Andric shared_future<void> share() noexcept; 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andric // retrieving the value 215*0b57cec5SDimitry Andric void get(); 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric // functions to check state 218*0b57cec5SDimitry Andric bool valid() const noexcept; 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric void wait() const; 221*0b57cec5SDimitry Andric template <class Rep, class Period> 222*0b57cec5SDimitry Andric future_status 223*0b57cec5SDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 224*0b57cec5SDimitry Andric template <class Clock, class Duration> 225*0b57cec5SDimitry Andric future_status 226*0b57cec5SDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 227*0b57cec5SDimitry Andric}; 228*0b57cec5SDimitry Andric 229*0b57cec5SDimitry Andrictemplate <class R> 230*0b57cec5SDimitry Andricclass shared_future 231*0b57cec5SDimitry Andric{ 232*0b57cec5SDimitry Andricpublic: 233*0b57cec5SDimitry Andric shared_future() noexcept; 234*0b57cec5SDimitry Andric shared_future(const shared_future& rhs); 235*0b57cec5SDimitry Andric shared_future(future<R>&&) noexcept; 236*0b57cec5SDimitry Andric shared_future(shared_future&& rhs) noexcept; 237*0b57cec5SDimitry Andric ~shared_future(); 238*0b57cec5SDimitry Andric shared_future& operator=(const shared_future& rhs); 239*0b57cec5SDimitry Andric shared_future& operator=(shared_future&& rhs) noexcept; 240*0b57cec5SDimitry Andric 241*0b57cec5SDimitry Andric // retrieving the value 242*0b57cec5SDimitry Andric const R& get() const; 243*0b57cec5SDimitry Andric 244*0b57cec5SDimitry Andric // functions to check state 245*0b57cec5SDimitry Andric bool valid() const noexcept; 246*0b57cec5SDimitry Andric 247*0b57cec5SDimitry Andric void wait() const; 248*0b57cec5SDimitry Andric template <class Rep, class Period> 249*0b57cec5SDimitry Andric future_status 250*0b57cec5SDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 251*0b57cec5SDimitry Andric template <class Clock, class Duration> 252*0b57cec5SDimitry Andric future_status 253*0b57cec5SDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 254*0b57cec5SDimitry Andric}; 255*0b57cec5SDimitry Andric 256*0b57cec5SDimitry Andrictemplate <class R> 257*0b57cec5SDimitry Andricclass shared_future<R&> 258*0b57cec5SDimitry Andric{ 259*0b57cec5SDimitry Andricpublic: 260*0b57cec5SDimitry Andric shared_future() noexcept; 261*0b57cec5SDimitry Andric shared_future(const shared_future& rhs); 262*0b57cec5SDimitry Andric shared_future(future<R&>&&) noexcept; 263*0b57cec5SDimitry Andric shared_future(shared_future&& rhs) noexcept; 264*0b57cec5SDimitry Andric ~shared_future(); 265*0b57cec5SDimitry Andric shared_future& operator=(const shared_future& rhs); 266*0b57cec5SDimitry Andric shared_future& operator=(shared_future&& rhs) noexcept; 267*0b57cec5SDimitry Andric 268*0b57cec5SDimitry Andric // retrieving the value 269*0b57cec5SDimitry Andric R& get() const; 270*0b57cec5SDimitry Andric 271*0b57cec5SDimitry Andric // functions to check state 272*0b57cec5SDimitry Andric bool valid() const noexcept; 273*0b57cec5SDimitry Andric 274*0b57cec5SDimitry Andric void wait() const; 275*0b57cec5SDimitry Andric template <class Rep, class Period> 276*0b57cec5SDimitry Andric future_status 277*0b57cec5SDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 278*0b57cec5SDimitry Andric template <class Clock, class Duration> 279*0b57cec5SDimitry Andric future_status 280*0b57cec5SDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 281*0b57cec5SDimitry Andric}; 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andrictemplate <> 284*0b57cec5SDimitry Andricclass shared_future<void> 285*0b57cec5SDimitry Andric{ 286*0b57cec5SDimitry Andricpublic: 287*0b57cec5SDimitry Andric shared_future() noexcept; 288*0b57cec5SDimitry Andric shared_future(const shared_future& rhs); 289*0b57cec5SDimitry Andric shared_future(future<void>&&) noexcept; 290*0b57cec5SDimitry Andric shared_future(shared_future&& rhs) noexcept; 291*0b57cec5SDimitry Andric ~shared_future(); 292*0b57cec5SDimitry Andric shared_future& operator=(const shared_future& rhs); 293*0b57cec5SDimitry Andric shared_future& operator=(shared_future&& rhs) noexcept; 294*0b57cec5SDimitry Andric 295*0b57cec5SDimitry Andric // retrieving the value 296*0b57cec5SDimitry Andric void get() const; 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric // functions to check state 299*0b57cec5SDimitry Andric bool valid() const noexcept; 300*0b57cec5SDimitry Andric 301*0b57cec5SDimitry Andric void wait() const; 302*0b57cec5SDimitry Andric template <class Rep, class Period> 303*0b57cec5SDimitry Andric future_status 304*0b57cec5SDimitry Andric wait_for(const chrono::duration<Rep, Period>& rel_time) const; 305*0b57cec5SDimitry Andric template <class Clock, class Duration> 306*0b57cec5SDimitry Andric future_status 307*0b57cec5SDimitry Andric wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 308*0b57cec5SDimitry Andric}; 309*0b57cec5SDimitry Andric 310*0b57cec5SDimitry Andrictemplate <class F, class... Args> 311*0b57cec5SDimitry Andric future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 312*0b57cec5SDimitry Andric async(F&& f, Args&&... args); 313*0b57cec5SDimitry Andric 314*0b57cec5SDimitry Andrictemplate <class F, class... Args> 315*0b57cec5SDimitry Andric future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 316*0b57cec5SDimitry Andric async(launch policy, F&& f, Args&&... args); 317*0b57cec5SDimitry Andric 318*0b57cec5SDimitry Andrictemplate <class> class packaged_task; // undefined 319*0b57cec5SDimitry Andric 320*0b57cec5SDimitry Andrictemplate <class R, class... ArgTypes> 321*0b57cec5SDimitry Andricclass packaged_task<R(ArgTypes...)> 322*0b57cec5SDimitry Andric{ 323*0b57cec5SDimitry Andricpublic: 324*0b57cec5SDimitry Andric typedef R result_type; // extension 325*0b57cec5SDimitry Andric 326*0b57cec5SDimitry Andric // construction and destruction 327*0b57cec5SDimitry Andric packaged_task() noexcept; 328*0b57cec5SDimitry Andric template <class F> 329*0b57cec5SDimitry Andric explicit packaged_task(F&& f); 330*0b57cec5SDimitry Andric template <class F, class Allocator> 331*0b57cec5SDimitry Andric packaged_task(allocator_arg_t, const Allocator& a, F&& f); 332*0b57cec5SDimitry Andric ~packaged_task(); 333*0b57cec5SDimitry Andric 334*0b57cec5SDimitry Andric // no copy 335*0b57cec5SDimitry Andric packaged_task(const packaged_task&) = delete; 336*0b57cec5SDimitry Andric packaged_task& operator=(const packaged_task&) = delete; 337*0b57cec5SDimitry Andric 338*0b57cec5SDimitry Andric // move support 339*0b57cec5SDimitry Andric packaged_task(packaged_task&& other) noexcept; 340*0b57cec5SDimitry Andric packaged_task& operator=(packaged_task&& other) noexcept; 341*0b57cec5SDimitry Andric void swap(packaged_task& other) noexcept; 342*0b57cec5SDimitry Andric 343*0b57cec5SDimitry Andric bool valid() const noexcept; 344*0b57cec5SDimitry Andric 345*0b57cec5SDimitry Andric // result retrieval 346*0b57cec5SDimitry Andric future<R> get_future(); 347*0b57cec5SDimitry Andric 348*0b57cec5SDimitry Andric // execution 349*0b57cec5SDimitry Andric void operator()(ArgTypes... ); 350*0b57cec5SDimitry Andric void make_ready_at_thread_exit(ArgTypes...); 351*0b57cec5SDimitry Andric 352*0b57cec5SDimitry Andric void reset(); 353*0b57cec5SDimitry Andric}; 354*0b57cec5SDimitry Andric 355*0b57cec5SDimitry Andrictemplate <class R> 356*0b57cec5SDimitry Andric void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept; 357*0b57cec5SDimitry Andric 358*0b57cec5SDimitry Andrictemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; 359*0b57cec5SDimitry Andric 360*0b57cec5SDimitry Andric} // std 361*0b57cec5SDimitry Andric 362*0b57cec5SDimitry Andric*/ 363*0b57cec5SDimitry Andric 364*0b57cec5SDimitry Andric#include <__config> 365*0b57cec5SDimitry Andric#include <system_error> 366*0b57cec5SDimitry Andric#include <memory> 367*0b57cec5SDimitry Andric#include <chrono> 368*0b57cec5SDimitry Andric#include <exception> 369*0b57cec5SDimitry Andric#include <mutex> 370*0b57cec5SDimitry Andric#include <thread> 371*0b57cec5SDimitry Andric 372*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 373*0b57cec5SDimitry Andric#pragma GCC system_header 374*0b57cec5SDimitry Andric#endif 375*0b57cec5SDimitry Andric 376*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS 377*0b57cec5SDimitry Andric#error <future> is not supported on this single threaded system 378*0b57cec5SDimitry Andric#else // !_LIBCPP_HAS_NO_THREADS 379*0b57cec5SDimitry Andric 380*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 381*0b57cec5SDimitry Andric 382*0b57cec5SDimitry Andric//enum class future_errc 383*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_errc) 384*0b57cec5SDimitry Andric{ 385*0b57cec5SDimitry Andric future_already_retrieved = 1, 386*0b57cec5SDimitry Andric promise_already_satisfied, 387*0b57cec5SDimitry Andric no_state, 388*0b57cec5SDimitry Andric broken_promise 389*0b57cec5SDimitry Andric}; 390*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc) 391*0b57cec5SDimitry Andric 392*0b57cec5SDimitry Andrictemplate <> 393*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {}; 394*0b57cec5SDimitry Andric 395*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS 396*0b57cec5SDimitry Andrictemplate <> 397*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { }; 398*0b57cec5SDimitry Andric#endif 399*0b57cec5SDimitry Andric 400*0b57cec5SDimitry Andric//enum class launch 401*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(launch) 402*0b57cec5SDimitry Andric{ 403*0b57cec5SDimitry Andric async = 1, 404*0b57cec5SDimitry Andric deferred = 2, 405*0b57cec5SDimitry Andric any = async | deferred 406*0b57cec5SDimitry Andric}; 407*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch) 408*0b57cec5SDimitry Andric 409*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS 410*0b57cec5SDimitry Andric 411*0b57cec5SDimitry Andrictypedef underlying_type<launch>::type __launch_underlying_type; 412*0b57cec5SDimitry Andric 413*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 414*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 415*0b57cec5SDimitry Andriclaunch 416*0b57cec5SDimitry Andricoperator&(launch __x, launch __y) 417*0b57cec5SDimitry Andric{ 418*0b57cec5SDimitry Andric return static_cast<launch>(static_cast<__launch_underlying_type>(__x) & 419*0b57cec5SDimitry Andric static_cast<__launch_underlying_type>(__y)); 420*0b57cec5SDimitry Andric} 421*0b57cec5SDimitry Andric 422*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 423*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 424*0b57cec5SDimitry Andriclaunch 425*0b57cec5SDimitry Andricoperator|(launch __x, launch __y) 426*0b57cec5SDimitry Andric{ 427*0b57cec5SDimitry Andric return static_cast<launch>(static_cast<__launch_underlying_type>(__x) | 428*0b57cec5SDimitry Andric static_cast<__launch_underlying_type>(__y)); 429*0b57cec5SDimitry Andric} 430*0b57cec5SDimitry Andric 431*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 432*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 433*0b57cec5SDimitry Andriclaunch 434*0b57cec5SDimitry Andricoperator^(launch __x, launch __y) 435*0b57cec5SDimitry Andric{ 436*0b57cec5SDimitry Andric return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^ 437*0b57cec5SDimitry Andric static_cast<__launch_underlying_type>(__y)); 438*0b57cec5SDimitry Andric} 439*0b57cec5SDimitry Andric 440*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 441*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 442*0b57cec5SDimitry Andriclaunch 443*0b57cec5SDimitry Andricoperator~(launch __x) 444*0b57cec5SDimitry Andric{ 445*0b57cec5SDimitry Andric return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3); 446*0b57cec5SDimitry Andric} 447*0b57cec5SDimitry Andric 448*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 449*0b57cec5SDimitry Andriclaunch& 450*0b57cec5SDimitry Andricoperator&=(launch& __x, launch __y) 451*0b57cec5SDimitry Andric{ 452*0b57cec5SDimitry Andric __x = __x & __y; return __x; 453*0b57cec5SDimitry Andric} 454*0b57cec5SDimitry Andric 455*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 456*0b57cec5SDimitry Andriclaunch& 457*0b57cec5SDimitry Andricoperator|=(launch& __x, launch __y) 458*0b57cec5SDimitry Andric{ 459*0b57cec5SDimitry Andric __x = __x | __y; return __x; 460*0b57cec5SDimitry Andric} 461*0b57cec5SDimitry Andric 462*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 463*0b57cec5SDimitry Andriclaunch& 464*0b57cec5SDimitry Andricoperator^=(launch& __x, launch __y) 465*0b57cec5SDimitry Andric{ 466*0b57cec5SDimitry Andric __x = __x ^ __y; return __x; 467*0b57cec5SDimitry Andric} 468*0b57cec5SDimitry Andric 469*0b57cec5SDimitry Andric#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS 470*0b57cec5SDimitry Andric 471*0b57cec5SDimitry Andric//enum class future_status 472*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_status) 473*0b57cec5SDimitry Andric{ 474*0b57cec5SDimitry Andric ready, 475*0b57cec5SDimitry Andric timeout, 476*0b57cec5SDimitry Andric deferred 477*0b57cec5SDimitry Andric}; 478*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status) 479*0b57cec5SDimitry Andric 480*0b57cec5SDimitry Andric_LIBCPP_FUNC_VIS 481*0b57cec5SDimitry Andricconst error_category& future_category() _NOEXCEPT; 482*0b57cec5SDimitry Andric 483*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 484*0b57cec5SDimitry Andricerror_code 485*0b57cec5SDimitry Andricmake_error_code(future_errc __e) _NOEXCEPT 486*0b57cec5SDimitry Andric{ 487*0b57cec5SDimitry Andric return error_code(static_cast<int>(__e), future_category()); 488*0b57cec5SDimitry Andric} 489*0b57cec5SDimitry Andric 490*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 491*0b57cec5SDimitry Andricerror_condition 492*0b57cec5SDimitry Andricmake_error_condition(future_errc __e) _NOEXCEPT 493*0b57cec5SDimitry Andric{ 494*0b57cec5SDimitry Andric return error_condition(static_cast<int>(__e), future_category()); 495*0b57cec5SDimitry Andric} 496*0b57cec5SDimitry Andric 497*0b57cec5SDimitry Andricclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error 498*0b57cec5SDimitry Andric : public logic_error 499*0b57cec5SDimitry Andric{ 500*0b57cec5SDimitry Andric error_code __ec_; 501*0b57cec5SDimitry Andricpublic: 502*0b57cec5SDimitry Andric future_error(error_code __ec); 503*0b57cec5SDimitry Andric#if _LIBCPP_STD_VERS > 14 504*0b57cec5SDimitry Andric explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {} 505*0b57cec5SDimitry Andric#endif 506*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 507*0b57cec5SDimitry Andric const error_code& code() const _NOEXCEPT {return __ec_;} 508*0b57cec5SDimitry Andric 509*0b57cec5SDimitry Andric virtual ~future_error() _NOEXCEPT; 510*0b57cec5SDimitry Andric}; 511*0b57cec5SDimitry Andric 512*0b57cec5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 513*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 514*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_FUTURE_ERROR 515*0b57cec5SDimitry Andric#endif 516*0b57cec5SDimitry Andricvoid __throw_future_error(future_errc _Ev) 517*0b57cec5SDimitry Andric{ 518*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 519*0b57cec5SDimitry Andric throw future_error(make_error_code(_Ev)); 520*0b57cec5SDimitry Andric#else 521*0b57cec5SDimitry Andric ((void)_Ev); 522*0b57cec5SDimitry Andric _VSTD::abort(); 523*0b57cec5SDimitry Andric#endif 524*0b57cec5SDimitry Andric} 525*0b57cec5SDimitry Andric 526*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state 527*0b57cec5SDimitry Andric : public __shared_count 528*0b57cec5SDimitry Andric{ 529*0b57cec5SDimitry Andricprotected: 530*0b57cec5SDimitry Andric exception_ptr __exception_; 531*0b57cec5SDimitry Andric mutable mutex __mut_; 532*0b57cec5SDimitry Andric mutable condition_variable __cv_; 533*0b57cec5SDimitry Andric unsigned __state_; 534*0b57cec5SDimitry Andric 535*0b57cec5SDimitry Andric virtual void __on_zero_shared() _NOEXCEPT; 536*0b57cec5SDimitry Andric void __sub_wait(unique_lock<mutex>& __lk); 537*0b57cec5SDimitry Andricpublic: 538*0b57cec5SDimitry Andric enum 539*0b57cec5SDimitry Andric { 540*0b57cec5SDimitry Andric __constructed = 1, 541*0b57cec5SDimitry Andric __future_attached = 2, 542*0b57cec5SDimitry Andric ready = 4, 543*0b57cec5SDimitry Andric deferred = 8 544*0b57cec5SDimitry Andric }; 545*0b57cec5SDimitry Andric 546*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 547*0b57cec5SDimitry Andric __assoc_sub_state() : __state_(0) {} 548*0b57cec5SDimitry Andric 549*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 550*0b57cec5SDimitry Andric bool __has_value() const 551*0b57cec5SDimitry Andric {return (__state_ & __constructed) || (__exception_ != nullptr);} 552*0b57cec5SDimitry Andric 553*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 554*0b57cec5SDimitry Andric void __attach_future() { 555*0b57cec5SDimitry Andric lock_guard<mutex> __lk(__mut_); 556*0b57cec5SDimitry Andric bool __has_future_attached = (__state_ & __future_attached) != 0; 557*0b57cec5SDimitry Andric if (__has_future_attached) 558*0b57cec5SDimitry Andric __throw_future_error(future_errc::future_already_retrieved); 559*0b57cec5SDimitry Andric this->__add_shared(); 560*0b57cec5SDimitry Andric __state_ |= __future_attached; 561*0b57cec5SDimitry Andric } 562*0b57cec5SDimitry Andric 563*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 564*0b57cec5SDimitry Andric void __set_deferred() {__state_ |= deferred;} 565*0b57cec5SDimitry Andric 566*0b57cec5SDimitry Andric void __make_ready(); 567*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 568*0b57cec5SDimitry Andric bool __is_ready() const {return (__state_ & ready) != 0;} 569*0b57cec5SDimitry Andric 570*0b57cec5SDimitry Andric void set_value(); 571*0b57cec5SDimitry Andric void set_value_at_thread_exit(); 572*0b57cec5SDimitry Andric 573*0b57cec5SDimitry Andric void set_exception(exception_ptr __p); 574*0b57cec5SDimitry Andric void set_exception_at_thread_exit(exception_ptr __p); 575*0b57cec5SDimitry Andric 576*0b57cec5SDimitry Andric void copy(); 577*0b57cec5SDimitry Andric 578*0b57cec5SDimitry Andric void wait(); 579*0b57cec5SDimitry Andric template <class _Rep, class _Period> 580*0b57cec5SDimitry Andric future_status 581*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 582*0b57cec5SDimitry Andric wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; 583*0b57cec5SDimitry Andric template <class _Clock, class _Duration> 584*0b57cec5SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 585*0b57cec5SDimitry Andric future_status 586*0b57cec5SDimitry Andric wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const; 587*0b57cec5SDimitry Andric 588*0b57cec5SDimitry Andric virtual void __execute(); 589*0b57cec5SDimitry Andric}; 590*0b57cec5SDimitry Andric 591*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration> 592*0b57cec5SDimitry Andricfuture_status 593*0b57cec5SDimitry Andric__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 594*0b57cec5SDimitry Andric{ 595*0b57cec5SDimitry Andric unique_lock<mutex> __lk(__mut_); 596*0b57cec5SDimitry Andric if (__state_ & deferred) 597*0b57cec5SDimitry Andric return future_status::deferred; 598*0b57cec5SDimitry Andric while (!(__state_ & ready) && _Clock::now() < __abs_time) 599*0b57cec5SDimitry Andric __cv_.wait_until(__lk, __abs_time); 600*0b57cec5SDimitry Andric if (__state_ & ready) 601*0b57cec5SDimitry Andric return future_status::ready; 602*0b57cec5SDimitry Andric return future_status::timeout; 603*0b57cec5SDimitry Andric} 604*0b57cec5SDimitry Andric 605*0b57cec5SDimitry Andrictemplate <class _Rep, class _Period> 606*0b57cec5SDimitry Andricinline 607*0b57cec5SDimitry Andricfuture_status 608*0b57cec5SDimitry Andric__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 609*0b57cec5SDimitry Andric{ 610*0b57cec5SDimitry Andric return wait_until(chrono::steady_clock::now() + __rel_time); 611*0b57cec5SDimitry Andric} 612*0b57cec5SDimitry Andric 613*0b57cec5SDimitry Andrictemplate <class _Rp> 614*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state 615*0b57cec5SDimitry Andric : public __assoc_sub_state 616*0b57cec5SDimitry Andric{ 617*0b57cec5SDimitry Andric typedef __assoc_sub_state base; 618*0b57cec5SDimitry Andric typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up; 619*0b57cec5SDimitry Andricprotected: 620*0b57cec5SDimitry Andric _Up __value_; 621*0b57cec5SDimitry Andric 622*0b57cec5SDimitry Andric virtual void __on_zero_shared() _NOEXCEPT; 623*0b57cec5SDimitry Andricpublic: 624*0b57cec5SDimitry Andric 625*0b57cec5SDimitry Andric template <class _Arg> 626*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 627*0b57cec5SDimitry Andric void set_value(_Arg&& __arg); 628*0b57cec5SDimitry Andric#else 629*0b57cec5SDimitry Andric void set_value(_Arg& __arg); 630*0b57cec5SDimitry Andric#endif 631*0b57cec5SDimitry Andric 632*0b57cec5SDimitry Andric template <class _Arg> 633*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 634*0b57cec5SDimitry Andric void set_value_at_thread_exit(_Arg&& __arg); 635*0b57cec5SDimitry Andric#else 636*0b57cec5SDimitry Andric void set_value_at_thread_exit(_Arg& __arg); 637*0b57cec5SDimitry Andric#endif 638*0b57cec5SDimitry Andric 639*0b57cec5SDimitry Andric _Rp move(); 640*0b57cec5SDimitry Andric typename add_lvalue_reference<_Rp>::type copy(); 641*0b57cec5SDimitry Andric}; 642*0b57cec5SDimitry Andric 643*0b57cec5SDimitry Andrictemplate <class _Rp> 644*0b57cec5SDimitry Andricvoid 645*0b57cec5SDimitry Andric__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT 646*0b57cec5SDimitry Andric{ 647*0b57cec5SDimitry Andric if (this->__state_ & base::__constructed) 648*0b57cec5SDimitry Andric reinterpret_cast<_Rp*>(&__value_)->~_Rp(); 649*0b57cec5SDimitry Andric delete this; 650*0b57cec5SDimitry Andric} 651*0b57cec5SDimitry Andric 652*0b57cec5SDimitry Andrictemplate <class _Rp> 653*0b57cec5SDimitry Andrictemplate <class _Arg> 654*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_FUTURE 655*0b57cec5SDimitry Andricvoid 656*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 657*0b57cec5SDimitry Andric__assoc_state<_Rp>::set_value(_Arg&& __arg) 658*0b57cec5SDimitry Andric#else 659*0b57cec5SDimitry Andric__assoc_state<_Rp>::set_value(_Arg& __arg) 660*0b57cec5SDimitry Andric#endif 661*0b57cec5SDimitry Andric{ 662*0b57cec5SDimitry Andric unique_lock<mutex> __lk(this->__mut_); 663*0b57cec5SDimitry Andric if (this->__has_value()) 664*0b57cec5SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 665*0b57cec5SDimitry Andric ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); 666*0b57cec5SDimitry Andric this->__state_ |= base::__constructed | base::ready; 667*0b57cec5SDimitry Andric __cv_.notify_all(); 668*0b57cec5SDimitry Andric} 669*0b57cec5SDimitry Andric 670*0b57cec5SDimitry Andrictemplate <class _Rp> 671*0b57cec5SDimitry Andrictemplate <class _Arg> 672*0b57cec5SDimitry Andricvoid 673*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 674*0b57cec5SDimitry Andric__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) 675*0b57cec5SDimitry Andric#else 676*0b57cec5SDimitry Andric__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg) 677*0b57cec5SDimitry Andric#endif 678*0b57cec5SDimitry Andric{ 679*0b57cec5SDimitry Andric unique_lock<mutex> __lk(this->__mut_); 680*0b57cec5SDimitry Andric if (this->__has_value()) 681*0b57cec5SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 682*0b57cec5SDimitry Andric ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); 683*0b57cec5SDimitry Andric this->__state_ |= base::__constructed; 684*0b57cec5SDimitry Andric __thread_local_data()->__make_ready_at_thread_exit(this); 685*0b57cec5SDimitry Andric} 686*0b57cec5SDimitry Andric 687*0b57cec5SDimitry Andrictemplate <class _Rp> 688*0b57cec5SDimitry Andric_Rp 689*0b57cec5SDimitry Andric__assoc_state<_Rp>::move() 690*0b57cec5SDimitry Andric{ 691*0b57cec5SDimitry Andric unique_lock<mutex> __lk(this->__mut_); 692*0b57cec5SDimitry Andric this->__sub_wait(__lk); 693*0b57cec5SDimitry Andric if (this->__exception_ != nullptr) 694*0b57cec5SDimitry Andric rethrow_exception(this->__exception_); 695*0b57cec5SDimitry Andric return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_)); 696*0b57cec5SDimitry Andric} 697*0b57cec5SDimitry Andric 698*0b57cec5SDimitry Andrictemplate <class _Rp> 699*0b57cec5SDimitry Andrictypename add_lvalue_reference<_Rp>::type 700*0b57cec5SDimitry Andric__assoc_state<_Rp>::copy() 701*0b57cec5SDimitry Andric{ 702*0b57cec5SDimitry Andric unique_lock<mutex> __lk(this->__mut_); 703*0b57cec5SDimitry Andric this->__sub_wait(__lk); 704*0b57cec5SDimitry Andric if (this->__exception_ != nullptr) 705*0b57cec5SDimitry Andric rethrow_exception(this->__exception_); 706*0b57cec5SDimitry Andric return *reinterpret_cast<_Rp*>(&__value_); 707*0b57cec5SDimitry Andric} 708*0b57cec5SDimitry Andric 709*0b57cec5SDimitry Andrictemplate <class _Rp> 710*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&> 711*0b57cec5SDimitry Andric : public __assoc_sub_state 712*0b57cec5SDimitry Andric{ 713*0b57cec5SDimitry Andric typedef __assoc_sub_state base; 714*0b57cec5SDimitry Andric typedef _Rp* _Up; 715*0b57cec5SDimitry Andricprotected: 716*0b57cec5SDimitry Andric _Up __value_; 717*0b57cec5SDimitry Andric 718*0b57cec5SDimitry Andric virtual void __on_zero_shared() _NOEXCEPT; 719*0b57cec5SDimitry Andricpublic: 720*0b57cec5SDimitry Andric 721*0b57cec5SDimitry Andric void set_value(_Rp& __arg); 722*0b57cec5SDimitry Andric void set_value_at_thread_exit(_Rp& __arg); 723*0b57cec5SDimitry Andric 724*0b57cec5SDimitry Andric _Rp& copy(); 725*0b57cec5SDimitry Andric}; 726*0b57cec5SDimitry Andric 727*0b57cec5SDimitry Andrictemplate <class _Rp> 728*0b57cec5SDimitry Andricvoid 729*0b57cec5SDimitry Andric__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT 730*0b57cec5SDimitry Andric{ 731*0b57cec5SDimitry Andric delete this; 732*0b57cec5SDimitry Andric} 733*0b57cec5SDimitry Andric 734*0b57cec5SDimitry Andrictemplate <class _Rp> 735*0b57cec5SDimitry Andricvoid 736*0b57cec5SDimitry Andric__assoc_state<_Rp&>::set_value(_Rp& __arg) 737*0b57cec5SDimitry Andric{ 738*0b57cec5SDimitry Andric unique_lock<mutex> __lk(this->__mut_); 739*0b57cec5SDimitry Andric if (this->__has_value()) 740*0b57cec5SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 741*0b57cec5SDimitry Andric __value_ = _VSTD::addressof(__arg); 742*0b57cec5SDimitry Andric this->__state_ |= base::__constructed | base::ready; 743*0b57cec5SDimitry Andric __cv_.notify_all(); 744*0b57cec5SDimitry Andric} 745*0b57cec5SDimitry Andric 746*0b57cec5SDimitry Andrictemplate <class _Rp> 747*0b57cec5SDimitry Andricvoid 748*0b57cec5SDimitry Andric__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) 749*0b57cec5SDimitry Andric{ 750*0b57cec5SDimitry Andric unique_lock<mutex> __lk(this->__mut_); 751*0b57cec5SDimitry Andric if (this->__has_value()) 752*0b57cec5SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 753*0b57cec5SDimitry Andric __value_ = _VSTD::addressof(__arg); 754*0b57cec5SDimitry Andric this->__state_ |= base::__constructed; 755*0b57cec5SDimitry Andric __thread_local_data()->__make_ready_at_thread_exit(this); 756*0b57cec5SDimitry Andric} 757*0b57cec5SDimitry Andric 758*0b57cec5SDimitry Andrictemplate <class _Rp> 759*0b57cec5SDimitry Andric_Rp& 760*0b57cec5SDimitry Andric__assoc_state<_Rp&>::copy() 761*0b57cec5SDimitry Andric{ 762*0b57cec5SDimitry Andric unique_lock<mutex> __lk(this->__mut_); 763*0b57cec5SDimitry Andric this->__sub_wait(__lk); 764*0b57cec5SDimitry Andric if (this->__exception_ != nullptr) 765*0b57cec5SDimitry Andric rethrow_exception(this->__exception_); 766*0b57cec5SDimitry Andric return *__value_; 767*0b57cec5SDimitry Andric} 768*0b57cec5SDimitry Andric 769*0b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc> 770*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc 771*0b57cec5SDimitry Andric : public __assoc_state<_Rp> 772*0b57cec5SDimitry Andric{ 773*0b57cec5SDimitry Andric typedef __assoc_state<_Rp> base; 774*0b57cec5SDimitry Andric _Alloc __alloc_; 775*0b57cec5SDimitry Andric 776*0b57cec5SDimitry Andric virtual void __on_zero_shared() _NOEXCEPT; 777*0b57cec5SDimitry Andricpublic: 778*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 779*0b57cec5SDimitry Andric explicit __assoc_state_alloc(const _Alloc& __a) 780*0b57cec5SDimitry Andric : __alloc_(__a) {} 781*0b57cec5SDimitry Andric}; 782*0b57cec5SDimitry Andric 783*0b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc> 784*0b57cec5SDimitry Andricvoid 785*0b57cec5SDimitry Andric__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT 786*0b57cec5SDimitry Andric{ 787*0b57cec5SDimitry Andric if (this->__state_ & base::__constructed) 788*0b57cec5SDimitry Andric reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp(); 789*0b57cec5SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; 790*0b57cec5SDimitry Andric typedef allocator_traits<_Al> _ATraits; 791*0b57cec5SDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 792*0b57cec5SDimitry Andric _Al __a(__alloc_); 793*0b57cec5SDimitry Andric this->~__assoc_state_alloc(); 794*0b57cec5SDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 795*0b57cec5SDimitry Andric} 796*0b57cec5SDimitry Andric 797*0b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc> 798*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc> 799*0b57cec5SDimitry Andric : public __assoc_state<_Rp&> 800*0b57cec5SDimitry Andric{ 801*0b57cec5SDimitry Andric typedef __assoc_state<_Rp&> base; 802*0b57cec5SDimitry Andric _Alloc __alloc_; 803*0b57cec5SDimitry Andric 804*0b57cec5SDimitry Andric virtual void __on_zero_shared() _NOEXCEPT; 805*0b57cec5SDimitry Andricpublic: 806*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 807*0b57cec5SDimitry Andric explicit __assoc_state_alloc(const _Alloc& __a) 808*0b57cec5SDimitry Andric : __alloc_(__a) {} 809*0b57cec5SDimitry Andric}; 810*0b57cec5SDimitry Andric 811*0b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc> 812*0b57cec5SDimitry Andricvoid 813*0b57cec5SDimitry Andric__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT 814*0b57cec5SDimitry Andric{ 815*0b57cec5SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; 816*0b57cec5SDimitry Andric typedef allocator_traits<_Al> _ATraits; 817*0b57cec5SDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 818*0b57cec5SDimitry Andric _Al __a(__alloc_); 819*0b57cec5SDimitry Andric this->~__assoc_state_alloc(); 820*0b57cec5SDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 821*0b57cec5SDimitry Andric} 822*0b57cec5SDimitry Andric 823*0b57cec5SDimitry Andrictemplate <class _Alloc> 824*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc 825*0b57cec5SDimitry Andric : public __assoc_sub_state 826*0b57cec5SDimitry Andric{ 827*0b57cec5SDimitry Andric typedef __assoc_sub_state base; 828*0b57cec5SDimitry Andric _Alloc __alloc_; 829*0b57cec5SDimitry Andric 830*0b57cec5SDimitry Andric virtual void __on_zero_shared() _NOEXCEPT; 831*0b57cec5SDimitry Andricpublic: 832*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 833*0b57cec5SDimitry Andric explicit __assoc_sub_state_alloc(const _Alloc& __a) 834*0b57cec5SDimitry Andric : __alloc_(__a) {} 835*0b57cec5SDimitry Andric}; 836*0b57cec5SDimitry Andric 837*0b57cec5SDimitry Andrictemplate <class _Alloc> 838*0b57cec5SDimitry Andricvoid 839*0b57cec5SDimitry Andric__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT 840*0b57cec5SDimitry Andric{ 841*0b57cec5SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al; 842*0b57cec5SDimitry Andric typedef allocator_traits<_Al> _ATraits; 843*0b57cec5SDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 844*0b57cec5SDimitry Andric _Al __a(__alloc_); 845*0b57cec5SDimitry Andric this->~__assoc_sub_state_alloc(); 846*0b57cec5SDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 847*0b57cec5SDimitry Andric} 848*0b57cec5SDimitry Andric 849*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 850*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state 851*0b57cec5SDimitry Andric : public __assoc_state<_Rp> 852*0b57cec5SDimitry Andric{ 853*0b57cec5SDimitry Andric typedef __assoc_state<_Rp> base; 854*0b57cec5SDimitry Andric 855*0b57cec5SDimitry Andric _Fp __func_; 856*0b57cec5SDimitry Andric 857*0b57cec5SDimitry Andricpublic: 858*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 859*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 860*0b57cec5SDimitry Andric explicit __deferred_assoc_state(_Fp&& __f); 861*0b57cec5SDimitry Andric#endif 862*0b57cec5SDimitry Andric 863*0b57cec5SDimitry Andric virtual void __execute(); 864*0b57cec5SDimitry Andric}; 865*0b57cec5SDimitry Andric 866*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 867*0b57cec5SDimitry Andric 868*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 869*0b57cec5SDimitry Andricinline 870*0b57cec5SDimitry Andric__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) 871*0b57cec5SDimitry Andric : __func_(_VSTD::forward<_Fp>(__f)) 872*0b57cec5SDimitry Andric{ 873*0b57cec5SDimitry Andric this->__set_deferred(); 874*0b57cec5SDimitry Andric} 875*0b57cec5SDimitry Andric 876*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 877*0b57cec5SDimitry Andric 878*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 879*0b57cec5SDimitry Andricvoid 880*0b57cec5SDimitry Andric__deferred_assoc_state<_Rp, _Fp>::__execute() 881*0b57cec5SDimitry Andric{ 882*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 883*0b57cec5SDimitry Andric try 884*0b57cec5SDimitry Andric { 885*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 886*0b57cec5SDimitry Andric this->set_value(__func_()); 887*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 888*0b57cec5SDimitry Andric } 889*0b57cec5SDimitry Andric catch (...) 890*0b57cec5SDimitry Andric { 891*0b57cec5SDimitry Andric this->set_exception(current_exception()); 892*0b57cec5SDimitry Andric } 893*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 894*0b57cec5SDimitry Andric} 895*0b57cec5SDimitry Andric 896*0b57cec5SDimitry Andrictemplate <class _Fp> 897*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp> 898*0b57cec5SDimitry Andric : public __assoc_sub_state 899*0b57cec5SDimitry Andric{ 900*0b57cec5SDimitry Andric typedef __assoc_sub_state base; 901*0b57cec5SDimitry Andric 902*0b57cec5SDimitry Andric _Fp __func_; 903*0b57cec5SDimitry Andric 904*0b57cec5SDimitry Andricpublic: 905*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 906*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 907*0b57cec5SDimitry Andric explicit __deferred_assoc_state(_Fp&& __f); 908*0b57cec5SDimitry Andric#endif 909*0b57cec5SDimitry Andric 910*0b57cec5SDimitry Andric virtual void __execute(); 911*0b57cec5SDimitry Andric}; 912*0b57cec5SDimitry Andric 913*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 914*0b57cec5SDimitry Andric 915*0b57cec5SDimitry Andrictemplate <class _Fp> 916*0b57cec5SDimitry Andricinline 917*0b57cec5SDimitry Andric__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) 918*0b57cec5SDimitry Andric : __func_(_VSTD::forward<_Fp>(__f)) 919*0b57cec5SDimitry Andric{ 920*0b57cec5SDimitry Andric this->__set_deferred(); 921*0b57cec5SDimitry Andric} 922*0b57cec5SDimitry Andric 923*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 924*0b57cec5SDimitry Andric 925*0b57cec5SDimitry Andrictemplate <class _Fp> 926*0b57cec5SDimitry Andricvoid 927*0b57cec5SDimitry Andric__deferred_assoc_state<void, _Fp>::__execute() 928*0b57cec5SDimitry Andric{ 929*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 930*0b57cec5SDimitry Andric try 931*0b57cec5SDimitry Andric { 932*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 933*0b57cec5SDimitry Andric __func_(); 934*0b57cec5SDimitry Andric this->set_value(); 935*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 936*0b57cec5SDimitry Andric } 937*0b57cec5SDimitry Andric catch (...) 938*0b57cec5SDimitry Andric { 939*0b57cec5SDimitry Andric this->set_exception(current_exception()); 940*0b57cec5SDimitry Andric } 941*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 942*0b57cec5SDimitry Andric} 943*0b57cec5SDimitry Andric 944*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 945*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state 946*0b57cec5SDimitry Andric : public __assoc_state<_Rp> 947*0b57cec5SDimitry Andric{ 948*0b57cec5SDimitry Andric typedef __assoc_state<_Rp> base; 949*0b57cec5SDimitry Andric 950*0b57cec5SDimitry Andric _Fp __func_; 951*0b57cec5SDimitry Andric 952*0b57cec5SDimitry Andric virtual void __on_zero_shared() _NOEXCEPT; 953*0b57cec5SDimitry Andricpublic: 954*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 955*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 956*0b57cec5SDimitry Andric explicit __async_assoc_state(_Fp&& __f); 957*0b57cec5SDimitry Andric#endif 958*0b57cec5SDimitry Andric 959*0b57cec5SDimitry Andric virtual void __execute(); 960*0b57cec5SDimitry Andric}; 961*0b57cec5SDimitry Andric 962*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 963*0b57cec5SDimitry Andric 964*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 965*0b57cec5SDimitry Andricinline 966*0b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) 967*0b57cec5SDimitry Andric : __func_(_VSTD::forward<_Fp>(__f)) 968*0b57cec5SDimitry Andric{ 969*0b57cec5SDimitry Andric} 970*0b57cec5SDimitry Andric 971*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 972*0b57cec5SDimitry Andric 973*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 974*0b57cec5SDimitry Andricvoid 975*0b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__execute() 976*0b57cec5SDimitry Andric{ 977*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 978*0b57cec5SDimitry Andric try 979*0b57cec5SDimitry Andric { 980*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 981*0b57cec5SDimitry Andric this->set_value(__func_()); 982*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 983*0b57cec5SDimitry Andric } 984*0b57cec5SDimitry Andric catch (...) 985*0b57cec5SDimitry Andric { 986*0b57cec5SDimitry Andric this->set_exception(current_exception()); 987*0b57cec5SDimitry Andric } 988*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 989*0b57cec5SDimitry Andric} 990*0b57cec5SDimitry Andric 991*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 992*0b57cec5SDimitry Andricvoid 993*0b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT 994*0b57cec5SDimitry Andric{ 995*0b57cec5SDimitry Andric this->wait(); 996*0b57cec5SDimitry Andric base::__on_zero_shared(); 997*0b57cec5SDimitry Andric} 998*0b57cec5SDimitry Andric 999*0b57cec5SDimitry Andrictemplate <class _Fp> 1000*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp> 1001*0b57cec5SDimitry Andric : public __assoc_sub_state 1002*0b57cec5SDimitry Andric{ 1003*0b57cec5SDimitry Andric typedef __assoc_sub_state base; 1004*0b57cec5SDimitry Andric 1005*0b57cec5SDimitry Andric _Fp __func_; 1006*0b57cec5SDimitry Andric 1007*0b57cec5SDimitry Andric virtual void __on_zero_shared() _NOEXCEPT; 1008*0b57cec5SDimitry Andricpublic: 1009*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1010*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1011*0b57cec5SDimitry Andric explicit __async_assoc_state(_Fp&& __f); 1012*0b57cec5SDimitry Andric#endif 1013*0b57cec5SDimitry Andric 1014*0b57cec5SDimitry Andric virtual void __execute(); 1015*0b57cec5SDimitry Andric}; 1016*0b57cec5SDimitry Andric 1017*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1018*0b57cec5SDimitry Andric 1019*0b57cec5SDimitry Andrictemplate <class _Fp> 1020*0b57cec5SDimitry Andricinline 1021*0b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) 1022*0b57cec5SDimitry Andric : __func_(_VSTD::forward<_Fp>(__f)) 1023*0b57cec5SDimitry Andric{ 1024*0b57cec5SDimitry Andric} 1025*0b57cec5SDimitry Andric 1026*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1027*0b57cec5SDimitry Andric 1028*0b57cec5SDimitry Andrictemplate <class _Fp> 1029*0b57cec5SDimitry Andricvoid 1030*0b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__execute() 1031*0b57cec5SDimitry Andric{ 1032*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 1033*0b57cec5SDimitry Andric try 1034*0b57cec5SDimitry Andric { 1035*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 1036*0b57cec5SDimitry Andric __func_(); 1037*0b57cec5SDimitry Andric this->set_value(); 1038*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 1039*0b57cec5SDimitry Andric } 1040*0b57cec5SDimitry Andric catch (...) 1041*0b57cec5SDimitry Andric { 1042*0b57cec5SDimitry Andric this->set_exception(current_exception()); 1043*0b57cec5SDimitry Andric } 1044*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 1045*0b57cec5SDimitry Andric} 1046*0b57cec5SDimitry Andric 1047*0b57cec5SDimitry Andrictemplate <class _Fp> 1048*0b57cec5SDimitry Andricvoid 1049*0b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT 1050*0b57cec5SDimitry Andric{ 1051*0b57cec5SDimitry Andric this->wait(); 1052*0b57cec5SDimitry Andric base::__on_zero_shared(); 1053*0b57cec5SDimitry Andric} 1054*0b57cec5SDimitry Andric 1055*0b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS promise; 1056*0b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future; 1057*0b57cec5SDimitry Andric 1058*0b57cec5SDimitry Andric// future 1059*0b57cec5SDimitry Andric 1060*0b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS future; 1061*0b57cec5SDimitry Andric 1062*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 1063*0b57cec5SDimitry Andricfuture<_Rp> 1064*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1065*0b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp&& __f); 1066*0b57cec5SDimitry Andric#else 1067*0b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp __f); 1068*0b57cec5SDimitry Andric#endif 1069*0b57cec5SDimitry Andric 1070*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 1071*0b57cec5SDimitry Andricfuture<_Rp> 1072*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1073*0b57cec5SDimitry Andric__make_async_assoc_state(_Fp&& __f); 1074*0b57cec5SDimitry Andric#else 1075*0b57cec5SDimitry Andric__make_async_assoc_state(_Fp __f); 1076*0b57cec5SDimitry Andric#endif 1077*0b57cec5SDimitry Andric 1078*0b57cec5SDimitry Andrictemplate <class _Rp> 1079*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future 1080*0b57cec5SDimitry Andric{ 1081*0b57cec5SDimitry Andric __assoc_state<_Rp>* __state_; 1082*0b57cec5SDimitry Andric 1083*0b57cec5SDimitry Andric explicit future(__assoc_state<_Rp>* __state); 1084*0b57cec5SDimitry Andric 1085*0b57cec5SDimitry Andric template <class> friend class promise; 1086*0b57cec5SDimitry Andric template <class> friend class shared_future; 1087*0b57cec5SDimitry Andric 1088*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1089*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1090*0b57cec5SDimitry Andric friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 1091*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1092*0b57cec5SDimitry Andric friend future<_R1> __make_async_assoc_state(_Fp&& __f); 1093*0b57cec5SDimitry Andric#else 1094*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1095*0b57cec5SDimitry Andric friend future<_R1> __make_deferred_assoc_state(_Fp __f); 1096*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1097*0b57cec5SDimitry Andric friend future<_R1> __make_async_assoc_state(_Fp __f); 1098*0b57cec5SDimitry Andric#endif 1099*0b57cec5SDimitry Andric 1100*0b57cec5SDimitry Andricpublic: 1101*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1102*0b57cec5SDimitry Andric future() _NOEXCEPT : __state_(nullptr) {} 1103*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1104*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1105*0b57cec5SDimitry Andric future(future&& __rhs) _NOEXCEPT 1106*0b57cec5SDimitry Andric : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1107*0b57cec5SDimitry Andric future(const future&) = delete; 1108*0b57cec5SDimitry Andric future& operator=(const future&) = delete; 1109*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1110*0b57cec5SDimitry Andric future& operator=(future&& __rhs) _NOEXCEPT 1111*0b57cec5SDimitry Andric { 1112*0b57cec5SDimitry Andric future(std::move(__rhs)).swap(*this); 1113*0b57cec5SDimitry Andric return *this; 1114*0b57cec5SDimitry Andric } 1115*0b57cec5SDimitry Andric#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1116*0b57cec5SDimitry Andricprivate: 1117*0b57cec5SDimitry Andric future(const future&); 1118*0b57cec5SDimitry Andric future& operator=(const future&); 1119*0b57cec5SDimitry Andricpublic: 1120*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1121*0b57cec5SDimitry Andric ~future(); 1122*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1123*0b57cec5SDimitry Andric shared_future<_Rp> share() _NOEXCEPT; 1124*0b57cec5SDimitry Andric 1125*0b57cec5SDimitry Andric // retrieving the value 1126*0b57cec5SDimitry Andric _Rp get(); 1127*0b57cec5SDimitry Andric 1128*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1129*0b57cec5SDimitry Andric void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1130*0b57cec5SDimitry Andric 1131*0b57cec5SDimitry Andric // functions to check state 1132*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1133*0b57cec5SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 1134*0b57cec5SDimitry Andric 1135*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1136*0b57cec5SDimitry Andric void wait() const {__state_->wait();} 1137*0b57cec5SDimitry Andric template <class _Rep, class _Period> 1138*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1139*0b57cec5SDimitry Andric future_status 1140*0b57cec5SDimitry Andric wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 1141*0b57cec5SDimitry Andric {return __state_->wait_for(__rel_time);} 1142*0b57cec5SDimitry Andric template <class _Clock, class _Duration> 1143*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1144*0b57cec5SDimitry Andric future_status 1145*0b57cec5SDimitry Andric wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 1146*0b57cec5SDimitry Andric {return __state_->wait_until(__abs_time);} 1147*0b57cec5SDimitry Andric}; 1148*0b57cec5SDimitry Andric 1149*0b57cec5SDimitry Andrictemplate <class _Rp> 1150*0b57cec5SDimitry Andricfuture<_Rp>::future(__assoc_state<_Rp>* __state) 1151*0b57cec5SDimitry Andric : __state_(__state) 1152*0b57cec5SDimitry Andric{ 1153*0b57cec5SDimitry Andric __state_->__attach_future(); 1154*0b57cec5SDimitry Andric} 1155*0b57cec5SDimitry Andric 1156*0b57cec5SDimitry Andricstruct __release_shared_count 1157*0b57cec5SDimitry Andric{ 1158*0b57cec5SDimitry Andric void operator()(__shared_count* p) {p->__release_shared();} 1159*0b57cec5SDimitry Andric}; 1160*0b57cec5SDimitry Andric 1161*0b57cec5SDimitry Andrictemplate <class _Rp> 1162*0b57cec5SDimitry Andricfuture<_Rp>::~future() 1163*0b57cec5SDimitry Andric{ 1164*0b57cec5SDimitry Andric if (__state_) 1165*0b57cec5SDimitry Andric __state_->__release_shared(); 1166*0b57cec5SDimitry Andric} 1167*0b57cec5SDimitry Andric 1168*0b57cec5SDimitry Andrictemplate <class _Rp> 1169*0b57cec5SDimitry Andric_Rp 1170*0b57cec5SDimitry Andricfuture<_Rp>::get() 1171*0b57cec5SDimitry Andric{ 1172*0b57cec5SDimitry Andric unique_ptr<__shared_count, __release_shared_count> __(__state_); 1173*0b57cec5SDimitry Andric __assoc_state<_Rp>* __s = __state_; 1174*0b57cec5SDimitry Andric __state_ = nullptr; 1175*0b57cec5SDimitry Andric return __s->move(); 1176*0b57cec5SDimitry Andric} 1177*0b57cec5SDimitry Andric 1178*0b57cec5SDimitry Andrictemplate <class _Rp> 1179*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&> 1180*0b57cec5SDimitry Andric{ 1181*0b57cec5SDimitry Andric __assoc_state<_Rp&>* __state_; 1182*0b57cec5SDimitry Andric 1183*0b57cec5SDimitry Andric explicit future(__assoc_state<_Rp&>* __state); 1184*0b57cec5SDimitry Andric 1185*0b57cec5SDimitry Andric template <class> friend class promise; 1186*0b57cec5SDimitry Andric template <class> friend class shared_future; 1187*0b57cec5SDimitry Andric 1188*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1189*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1190*0b57cec5SDimitry Andric friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 1191*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1192*0b57cec5SDimitry Andric friend future<_R1> __make_async_assoc_state(_Fp&& __f); 1193*0b57cec5SDimitry Andric#else 1194*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1195*0b57cec5SDimitry Andric friend future<_R1> __make_deferred_assoc_state(_Fp __f); 1196*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1197*0b57cec5SDimitry Andric friend future<_R1> __make_async_assoc_state(_Fp __f); 1198*0b57cec5SDimitry Andric#endif 1199*0b57cec5SDimitry Andric 1200*0b57cec5SDimitry Andricpublic: 1201*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1202*0b57cec5SDimitry Andric future() _NOEXCEPT : __state_(nullptr) {} 1203*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1204*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1205*0b57cec5SDimitry Andric future(future&& __rhs) _NOEXCEPT 1206*0b57cec5SDimitry Andric : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1207*0b57cec5SDimitry Andric future(const future&) = delete; 1208*0b57cec5SDimitry Andric future& operator=(const future&) = delete; 1209*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1210*0b57cec5SDimitry Andric future& operator=(future&& __rhs) _NOEXCEPT 1211*0b57cec5SDimitry Andric { 1212*0b57cec5SDimitry Andric future(std::move(__rhs)).swap(*this); 1213*0b57cec5SDimitry Andric return *this; 1214*0b57cec5SDimitry Andric } 1215*0b57cec5SDimitry Andric#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1216*0b57cec5SDimitry Andricprivate: 1217*0b57cec5SDimitry Andric future(const future&); 1218*0b57cec5SDimitry Andric future& operator=(const future&); 1219*0b57cec5SDimitry Andricpublic: 1220*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1221*0b57cec5SDimitry Andric ~future(); 1222*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1223*0b57cec5SDimitry Andric shared_future<_Rp&> share() _NOEXCEPT; 1224*0b57cec5SDimitry Andric 1225*0b57cec5SDimitry Andric // retrieving the value 1226*0b57cec5SDimitry Andric _Rp& get(); 1227*0b57cec5SDimitry Andric 1228*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1229*0b57cec5SDimitry Andric void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1230*0b57cec5SDimitry Andric 1231*0b57cec5SDimitry Andric // functions to check state 1232*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1233*0b57cec5SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 1234*0b57cec5SDimitry Andric 1235*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1236*0b57cec5SDimitry Andric void wait() const {__state_->wait();} 1237*0b57cec5SDimitry Andric template <class _Rep, class _Period> 1238*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1239*0b57cec5SDimitry Andric future_status 1240*0b57cec5SDimitry Andric wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 1241*0b57cec5SDimitry Andric {return __state_->wait_for(__rel_time);} 1242*0b57cec5SDimitry Andric template <class _Clock, class _Duration> 1243*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1244*0b57cec5SDimitry Andric future_status 1245*0b57cec5SDimitry Andric wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 1246*0b57cec5SDimitry Andric {return __state_->wait_until(__abs_time);} 1247*0b57cec5SDimitry Andric}; 1248*0b57cec5SDimitry Andric 1249*0b57cec5SDimitry Andrictemplate <class _Rp> 1250*0b57cec5SDimitry Andricfuture<_Rp&>::future(__assoc_state<_Rp&>* __state) 1251*0b57cec5SDimitry Andric : __state_(__state) 1252*0b57cec5SDimitry Andric{ 1253*0b57cec5SDimitry Andric __state_->__attach_future(); 1254*0b57cec5SDimitry Andric} 1255*0b57cec5SDimitry Andric 1256*0b57cec5SDimitry Andrictemplate <class _Rp> 1257*0b57cec5SDimitry Andricfuture<_Rp&>::~future() 1258*0b57cec5SDimitry Andric{ 1259*0b57cec5SDimitry Andric if (__state_) 1260*0b57cec5SDimitry Andric __state_->__release_shared(); 1261*0b57cec5SDimitry Andric} 1262*0b57cec5SDimitry Andric 1263*0b57cec5SDimitry Andrictemplate <class _Rp> 1264*0b57cec5SDimitry Andric_Rp& 1265*0b57cec5SDimitry Andricfuture<_Rp&>::get() 1266*0b57cec5SDimitry Andric{ 1267*0b57cec5SDimitry Andric unique_ptr<__shared_count, __release_shared_count> __(__state_); 1268*0b57cec5SDimitry Andric __assoc_state<_Rp&>* __s = __state_; 1269*0b57cec5SDimitry Andric __state_ = nullptr; 1270*0b57cec5SDimitry Andric return __s->copy(); 1271*0b57cec5SDimitry Andric} 1272*0b57cec5SDimitry Andric 1273*0b57cec5SDimitry Andrictemplate <> 1274*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void> 1275*0b57cec5SDimitry Andric{ 1276*0b57cec5SDimitry Andric __assoc_sub_state* __state_; 1277*0b57cec5SDimitry Andric 1278*0b57cec5SDimitry Andric explicit future(__assoc_sub_state* __state); 1279*0b57cec5SDimitry Andric 1280*0b57cec5SDimitry Andric template <class> friend class promise; 1281*0b57cec5SDimitry Andric template <class> friend class shared_future; 1282*0b57cec5SDimitry Andric 1283*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1284*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1285*0b57cec5SDimitry Andric friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 1286*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1287*0b57cec5SDimitry Andric friend future<_R1> __make_async_assoc_state(_Fp&& __f); 1288*0b57cec5SDimitry Andric#else 1289*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1290*0b57cec5SDimitry Andric friend future<_R1> __make_deferred_assoc_state(_Fp __f); 1291*0b57cec5SDimitry Andric template <class _R1, class _Fp> 1292*0b57cec5SDimitry Andric friend future<_R1> __make_async_assoc_state(_Fp __f); 1293*0b57cec5SDimitry Andric#endif 1294*0b57cec5SDimitry Andric 1295*0b57cec5SDimitry Andricpublic: 1296*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1297*0b57cec5SDimitry Andric future() _NOEXCEPT : __state_(nullptr) {} 1298*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1299*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1300*0b57cec5SDimitry Andric future(future&& __rhs) _NOEXCEPT 1301*0b57cec5SDimitry Andric : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1302*0b57cec5SDimitry Andric future(const future&) = delete; 1303*0b57cec5SDimitry Andric future& operator=(const future&) = delete; 1304*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1305*0b57cec5SDimitry Andric future& operator=(future&& __rhs) _NOEXCEPT 1306*0b57cec5SDimitry Andric { 1307*0b57cec5SDimitry Andric future(std::move(__rhs)).swap(*this); 1308*0b57cec5SDimitry Andric return *this; 1309*0b57cec5SDimitry Andric } 1310*0b57cec5SDimitry Andric#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1311*0b57cec5SDimitry Andricprivate: 1312*0b57cec5SDimitry Andric future(const future&); 1313*0b57cec5SDimitry Andric future& operator=(const future&); 1314*0b57cec5SDimitry Andricpublic: 1315*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1316*0b57cec5SDimitry Andric ~future(); 1317*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1318*0b57cec5SDimitry Andric shared_future<void> share() _NOEXCEPT; 1319*0b57cec5SDimitry Andric 1320*0b57cec5SDimitry Andric // retrieving the value 1321*0b57cec5SDimitry Andric void get(); 1322*0b57cec5SDimitry Andric 1323*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1324*0b57cec5SDimitry Andric void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1325*0b57cec5SDimitry Andric 1326*0b57cec5SDimitry Andric // functions to check state 1327*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1328*0b57cec5SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 1329*0b57cec5SDimitry Andric 1330*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1331*0b57cec5SDimitry Andric void wait() const {__state_->wait();} 1332*0b57cec5SDimitry Andric template <class _Rep, class _Period> 1333*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1334*0b57cec5SDimitry Andric future_status 1335*0b57cec5SDimitry Andric wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 1336*0b57cec5SDimitry Andric {return __state_->wait_for(__rel_time);} 1337*0b57cec5SDimitry Andric template <class _Clock, class _Duration> 1338*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1339*0b57cec5SDimitry Andric future_status 1340*0b57cec5SDimitry Andric wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 1341*0b57cec5SDimitry Andric {return __state_->wait_until(__abs_time);} 1342*0b57cec5SDimitry Andric}; 1343*0b57cec5SDimitry Andric 1344*0b57cec5SDimitry Andrictemplate <class _Rp> 1345*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 1346*0b57cec5SDimitry Andricvoid 1347*0b57cec5SDimitry Andricswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT 1348*0b57cec5SDimitry Andric{ 1349*0b57cec5SDimitry Andric __x.swap(__y); 1350*0b57cec5SDimitry Andric} 1351*0b57cec5SDimitry Andric 1352*0b57cec5SDimitry Andric// promise<R> 1353*0b57cec5SDimitry Andric 1354*0b57cec5SDimitry Andrictemplate <class _Callable> class packaged_task; 1355*0b57cec5SDimitry Andric 1356*0b57cec5SDimitry Andrictemplate <class _Rp> 1357*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise 1358*0b57cec5SDimitry Andric{ 1359*0b57cec5SDimitry Andric __assoc_state<_Rp>* __state_; 1360*0b57cec5SDimitry Andric 1361*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1362*0b57cec5SDimitry Andric explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1363*0b57cec5SDimitry Andric 1364*0b57cec5SDimitry Andric template <class> friend class packaged_task; 1365*0b57cec5SDimitry Andricpublic: 1366*0b57cec5SDimitry Andric promise(); 1367*0b57cec5SDimitry Andric template <class _Alloc> 1368*0b57cec5SDimitry Andric promise(allocator_arg_t, const _Alloc& __a); 1369*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1370*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1371*0b57cec5SDimitry Andric promise(promise&& __rhs) _NOEXCEPT 1372*0b57cec5SDimitry Andric : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1373*0b57cec5SDimitry Andric promise(const promise& __rhs) = delete; 1374*0b57cec5SDimitry Andric#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1375*0b57cec5SDimitry Andricprivate: 1376*0b57cec5SDimitry Andric promise(const promise& __rhs); 1377*0b57cec5SDimitry Andricpublic: 1378*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1379*0b57cec5SDimitry Andric ~promise(); 1380*0b57cec5SDimitry Andric 1381*0b57cec5SDimitry Andric // assignment 1382*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1383*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1384*0b57cec5SDimitry Andric promise& operator=(promise&& __rhs) _NOEXCEPT 1385*0b57cec5SDimitry Andric { 1386*0b57cec5SDimitry Andric promise(std::move(__rhs)).swap(*this); 1387*0b57cec5SDimitry Andric return *this; 1388*0b57cec5SDimitry Andric } 1389*0b57cec5SDimitry Andric promise& operator=(const promise& __rhs) = delete; 1390*0b57cec5SDimitry Andric#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1391*0b57cec5SDimitry Andricprivate: 1392*0b57cec5SDimitry Andric promise& operator=(const promise& __rhs); 1393*0b57cec5SDimitry Andricpublic: 1394*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1395*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1396*0b57cec5SDimitry Andric void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1397*0b57cec5SDimitry Andric 1398*0b57cec5SDimitry Andric // retrieving the result 1399*0b57cec5SDimitry Andric future<_Rp> get_future(); 1400*0b57cec5SDimitry Andric 1401*0b57cec5SDimitry Andric // setting the result 1402*0b57cec5SDimitry Andric void set_value(const _Rp& __r); 1403*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1404*0b57cec5SDimitry Andric void set_value(_Rp&& __r); 1405*0b57cec5SDimitry Andric#endif 1406*0b57cec5SDimitry Andric void set_exception(exception_ptr __p); 1407*0b57cec5SDimitry Andric 1408*0b57cec5SDimitry Andric // setting the result with deferred notification 1409*0b57cec5SDimitry Andric void set_value_at_thread_exit(const _Rp& __r); 1410*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1411*0b57cec5SDimitry Andric void set_value_at_thread_exit(_Rp&& __r); 1412*0b57cec5SDimitry Andric#endif 1413*0b57cec5SDimitry Andric void set_exception_at_thread_exit(exception_ptr __p); 1414*0b57cec5SDimitry Andric}; 1415*0b57cec5SDimitry Andric 1416*0b57cec5SDimitry Andrictemplate <class _Rp> 1417*0b57cec5SDimitry Andricpromise<_Rp>::promise() 1418*0b57cec5SDimitry Andric : __state_(new __assoc_state<_Rp>) 1419*0b57cec5SDimitry Andric{ 1420*0b57cec5SDimitry Andric} 1421*0b57cec5SDimitry Andric 1422*0b57cec5SDimitry Andrictemplate <class _Rp> 1423*0b57cec5SDimitry Andrictemplate <class _Alloc> 1424*0b57cec5SDimitry Andricpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) 1425*0b57cec5SDimitry Andric{ 1426*0b57cec5SDimitry Andric typedef __assoc_state_alloc<_Rp, _Alloc> _State; 1427*0b57cec5SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; 1428*0b57cec5SDimitry Andric typedef __allocator_destructor<_A2> _D2; 1429*0b57cec5SDimitry Andric _A2 __a(__a0); 1430*0b57cec5SDimitry Andric unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1431*0b57cec5SDimitry Andric ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0); 1432*0b57cec5SDimitry Andric __state_ = _VSTD::addressof(*__hold.release()); 1433*0b57cec5SDimitry Andric} 1434*0b57cec5SDimitry Andric 1435*0b57cec5SDimitry Andrictemplate <class _Rp> 1436*0b57cec5SDimitry Andricpromise<_Rp>::~promise() 1437*0b57cec5SDimitry Andric{ 1438*0b57cec5SDimitry Andric if (__state_) 1439*0b57cec5SDimitry Andric { 1440*0b57cec5SDimitry Andric if (!__state_->__has_value() && __state_->use_count() > 1) 1441*0b57cec5SDimitry Andric __state_->set_exception(make_exception_ptr( 1442*0b57cec5SDimitry Andric future_error(make_error_code(future_errc::broken_promise)) 1443*0b57cec5SDimitry Andric )); 1444*0b57cec5SDimitry Andric __state_->__release_shared(); 1445*0b57cec5SDimitry Andric } 1446*0b57cec5SDimitry Andric} 1447*0b57cec5SDimitry Andric 1448*0b57cec5SDimitry Andrictemplate <class _Rp> 1449*0b57cec5SDimitry Andricfuture<_Rp> 1450*0b57cec5SDimitry Andricpromise<_Rp>::get_future() 1451*0b57cec5SDimitry Andric{ 1452*0b57cec5SDimitry Andric if (__state_ == nullptr) 1453*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1454*0b57cec5SDimitry Andric return future<_Rp>(__state_); 1455*0b57cec5SDimitry Andric} 1456*0b57cec5SDimitry Andric 1457*0b57cec5SDimitry Andrictemplate <class _Rp> 1458*0b57cec5SDimitry Andricvoid 1459*0b57cec5SDimitry Andricpromise<_Rp>::set_value(const _Rp& __r) 1460*0b57cec5SDimitry Andric{ 1461*0b57cec5SDimitry Andric if (__state_ == nullptr) 1462*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1463*0b57cec5SDimitry Andric __state_->set_value(__r); 1464*0b57cec5SDimitry Andric} 1465*0b57cec5SDimitry Andric 1466*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1467*0b57cec5SDimitry Andric 1468*0b57cec5SDimitry Andrictemplate <class _Rp> 1469*0b57cec5SDimitry Andricvoid 1470*0b57cec5SDimitry Andricpromise<_Rp>::set_value(_Rp&& __r) 1471*0b57cec5SDimitry Andric{ 1472*0b57cec5SDimitry Andric if (__state_ == nullptr) 1473*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1474*0b57cec5SDimitry Andric __state_->set_value(_VSTD::move(__r)); 1475*0b57cec5SDimitry Andric} 1476*0b57cec5SDimitry Andric 1477*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1478*0b57cec5SDimitry Andric 1479*0b57cec5SDimitry Andrictemplate <class _Rp> 1480*0b57cec5SDimitry Andricvoid 1481*0b57cec5SDimitry Andricpromise<_Rp>::set_exception(exception_ptr __p) 1482*0b57cec5SDimitry Andric{ 1483*0b57cec5SDimitry Andric _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" ); 1484*0b57cec5SDimitry Andric if (__state_ == nullptr) 1485*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1486*0b57cec5SDimitry Andric __state_->set_exception(__p); 1487*0b57cec5SDimitry Andric} 1488*0b57cec5SDimitry Andric 1489*0b57cec5SDimitry Andrictemplate <class _Rp> 1490*0b57cec5SDimitry Andricvoid 1491*0b57cec5SDimitry Andricpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r) 1492*0b57cec5SDimitry Andric{ 1493*0b57cec5SDimitry Andric if (__state_ == nullptr) 1494*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1495*0b57cec5SDimitry Andric __state_->set_value_at_thread_exit(__r); 1496*0b57cec5SDimitry Andric} 1497*0b57cec5SDimitry Andric 1498*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1499*0b57cec5SDimitry Andric 1500*0b57cec5SDimitry Andrictemplate <class _Rp> 1501*0b57cec5SDimitry Andricvoid 1502*0b57cec5SDimitry Andricpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r) 1503*0b57cec5SDimitry Andric{ 1504*0b57cec5SDimitry Andric if (__state_ == nullptr) 1505*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1506*0b57cec5SDimitry Andric __state_->set_value_at_thread_exit(_VSTD::move(__r)); 1507*0b57cec5SDimitry Andric} 1508*0b57cec5SDimitry Andric 1509*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1510*0b57cec5SDimitry Andric 1511*0b57cec5SDimitry Andrictemplate <class _Rp> 1512*0b57cec5SDimitry Andricvoid 1513*0b57cec5SDimitry Andricpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) 1514*0b57cec5SDimitry Andric{ 1515*0b57cec5SDimitry Andric _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); 1516*0b57cec5SDimitry Andric if (__state_ == nullptr) 1517*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1518*0b57cec5SDimitry Andric __state_->set_exception_at_thread_exit(__p); 1519*0b57cec5SDimitry Andric} 1520*0b57cec5SDimitry Andric 1521*0b57cec5SDimitry Andric// promise<R&> 1522*0b57cec5SDimitry Andric 1523*0b57cec5SDimitry Andrictemplate <class _Rp> 1524*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&> 1525*0b57cec5SDimitry Andric{ 1526*0b57cec5SDimitry Andric __assoc_state<_Rp&>* __state_; 1527*0b57cec5SDimitry Andric 1528*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1529*0b57cec5SDimitry Andric explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1530*0b57cec5SDimitry Andric 1531*0b57cec5SDimitry Andric template <class> friend class packaged_task; 1532*0b57cec5SDimitry Andric 1533*0b57cec5SDimitry Andricpublic: 1534*0b57cec5SDimitry Andric promise(); 1535*0b57cec5SDimitry Andric template <class _Allocator> 1536*0b57cec5SDimitry Andric promise(allocator_arg_t, const _Allocator& __a); 1537*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1538*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1539*0b57cec5SDimitry Andric promise(promise&& __rhs) _NOEXCEPT 1540*0b57cec5SDimitry Andric : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1541*0b57cec5SDimitry Andric promise(const promise& __rhs) = delete; 1542*0b57cec5SDimitry Andric#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1543*0b57cec5SDimitry Andricprivate: 1544*0b57cec5SDimitry Andric promise(const promise& __rhs); 1545*0b57cec5SDimitry Andricpublic: 1546*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1547*0b57cec5SDimitry Andric ~promise(); 1548*0b57cec5SDimitry Andric 1549*0b57cec5SDimitry Andric // assignment 1550*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1551*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1552*0b57cec5SDimitry Andric promise& operator=(promise&& __rhs) _NOEXCEPT 1553*0b57cec5SDimitry Andric { 1554*0b57cec5SDimitry Andric promise(std::move(__rhs)).swap(*this); 1555*0b57cec5SDimitry Andric return *this; 1556*0b57cec5SDimitry Andric } 1557*0b57cec5SDimitry Andric promise& operator=(const promise& __rhs) = delete; 1558*0b57cec5SDimitry Andric#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1559*0b57cec5SDimitry Andricprivate: 1560*0b57cec5SDimitry Andric promise& operator=(const promise& __rhs); 1561*0b57cec5SDimitry Andricpublic: 1562*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1563*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1564*0b57cec5SDimitry Andric void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1565*0b57cec5SDimitry Andric 1566*0b57cec5SDimitry Andric // retrieving the result 1567*0b57cec5SDimitry Andric future<_Rp&> get_future(); 1568*0b57cec5SDimitry Andric 1569*0b57cec5SDimitry Andric // setting the result 1570*0b57cec5SDimitry Andric void set_value(_Rp& __r); 1571*0b57cec5SDimitry Andric void set_exception(exception_ptr __p); 1572*0b57cec5SDimitry Andric 1573*0b57cec5SDimitry Andric // setting the result with deferred notification 1574*0b57cec5SDimitry Andric void set_value_at_thread_exit(_Rp&); 1575*0b57cec5SDimitry Andric void set_exception_at_thread_exit(exception_ptr __p); 1576*0b57cec5SDimitry Andric}; 1577*0b57cec5SDimitry Andric 1578*0b57cec5SDimitry Andrictemplate <class _Rp> 1579*0b57cec5SDimitry Andricpromise<_Rp&>::promise() 1580*0b57cec5SDimitry Andric : __state_(new __assoc_state<_Rp&>) 1581*0b57cec5SDimitry Andric{ 1582*0b57cec5SDimitry Andric} 1583*0b57cec5SDimitry Andric 1584*0b57cec5SDimitry Andrictemplate <class _Rp> 1585*0b57cec5SDimitry Andrictemplate <class _Alloc> 1586*0b57cec5SDimitry Andricpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) 1587*0b57cec5SDimitry Andric{ 1588*0b57cec5SDimitry Andric typedef __assoc_state_alloc<_Rp&, _Alloc> _State; 1589*0b57cec5SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; 1590*0b57cec5SDimitry Andric typedef __allocator_destructor<_A2> _D2; 1591*0b57cec5SDimitry Andric _A2 __a(__a0); 1592*0b57cec5SDimitry Andric unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1593*0b57cec5SDimitry Andric ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0); 1594*0b57cec5SDimitry Andric __state_ = _VSTD::addressof(*__hold.release()); 1595*0b57cec5SDimitry Andric} 1596*0b57cec5SDimitry Andric 1597*0b57cec5SDimitry Andrictemplate <class _Rp> 1598*0b57cec5SDimitry Andricpromise<_Rp&>::~promise() 1599*0b57cec5SDimitry Andric{ 1600*0b57cec5SDimitry Andric if (__state_) 1601*0b57cec5SDimitry Andric { 1602*0b57cec5SDimitry Andric if (!__state_->__has_value() && __state_->use_count() > 1) 1603*0b57cec5SDimitry Andric __state_->set_exception(make_exception_ptr( 1604*0b57cec5SDimitry Andric future_error(make_error_code(future_errc::broken_promise)) 1605*0b57cec5SDimitry Andric )); 1606*0b57cec5SDimitry Andric __state_->__release_shared(); 1607*0b57cec5SDimitry Andric } 1608*0b57cec5SDimitry Andric} 1609*0b57cec5SDimitry Andric 1610*0b57cec5SDimitry Andrictemplate <class _Rp> 1611*0b57cec5SDimitry Andricfuture<_Rp&> 1612*0b57cec5SDimitry Andricpromise<_Rp&>::get_future() 1613*0b57cec5SDimitry Andric{ 1614*0b57cec5SDimitry Andric if (__state_ == nullptr) 1615*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1616*0b57cec5SDimitry Andric return future<_Rp&>(__state_); 1617*0b57cec5SDimitry Andric} 1618*0b57cec5SDimitry Andric 1619*0b57cec5SDimitry Andrictemplate <class _Rp> 1620*0b57cec5SDimitry Andricvoid 1621*0b57cec5SDimitry Andricpromise<_Rp&>::set_value(_Rp& __r) 1622*0b57cec5SDimitry Andric{ 1623*0b57cec5SDimitry Andric if (__state_ == nullptr) 1624*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1625*0b57cec5SDimitry Andric __state_->set_value(__r); 1626*0b57cec5SDimitry Andric} 1627*0b57cec5SDimitry Andric 1628*0b57cec5SDimitry Andrictemplate <class _Rp> 1629*0b57cec5SDimitry Andricvoid 1630*0b57cec5SDimitry Andricpromise<_Rp&>::set_exception(exception_ptr __p) 1631*0b57cec5SDimitry Andric{ 1632*0b57cec5SDimitry Andric _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" ); 1633*0b57cec5SDimitry Andric if (__state_ == nullptr) 1634*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1635*0b57cec5SDimitry Andric __state_->set_exception(__p); 1636*0b57cec5SDimitry Andric} 1637*0b57cec5SDimitry Andric 1638*0b57cec5SDimitry Andrictemplate <class _Rp> 1639*0b57cec5SDimitry Andricvoid 1640*0b57cec5SDimitry Andricpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r) 1641*0b57cec5SDimitry Andric{ 1642*0b57cec5SDimitry Andric if (__state_ == nullptr) 1643*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1644*0b57cec5SDimitry Andric __state_->set_value_at_thread_exit(__r); 1645*0b57cec5SDimitry Andric} 1646*0b57cec5SDimitry Andric 1647*0b57cec5SDimitry Andrictemplate <class _Rp> 1648*0b57cec5SDimitry Andricvoid 1649*0b57cec5SDimitry Andricpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) 1650*0b57cec5SDimitry Andric{ 1651*0b57cec5SDimitry Andric _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); 1652*0b57cec5SDimitry Andric if (__state_ == nullptr) 1653*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 1654*0b57cec5SDimitry Andric __state_->set_exception_at_thread_exit(__p); 1655*0b57cec5SDimitry Andric} 1656*0b57cec5SDimitry Andric 1657*0b57cec5SDimitry Andric// promise<void> 1658*0b57cec5SDimitry Andric 1659*0b57cec5SDimitry Andrictemplate <> 1660*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void> 1661*0b57cec5SDimitry Andric{ 1662*0b57cec5SDimitry Andric __assoc_sub_state* __state_; 1663*0b57cec5SDimitry Andric 1664*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1665*0b57cec5SDimitry Andric explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1666*0b57cec5SDimitry Andric 1667*0b57cec5SDimitry Andric template <class> friend class packaged_task; 1668*0b57cec5SDimitry Andric 1669*0b57cec5SDimitry Andricpublic: 1670*0b57cec5SDimitry Andric promise(); 1671*0b57cec5SDimitry Andric template <class _Allocator> 1672*0b57cec5SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 1673*0b57cec5SDimitry Andric promise(allocator_arg_t, const _Allocator& __a); 1674*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1675*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1676*0b57cec5SDimitry Andric promise(promise&& __rhs) _NOEXCEPT 1677*0b57cec5SDimitry Andric : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1678*0b57cec5SDimitry Andric promise(const promise& __rhs) = delete; 1679*0b57cec5SDimitry Andric#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1680*0b57cec5SDimitry Andricprivate: 1681*0b57cec5SDimitry Andric promise(const promise& __rhs); 1682*0b57cec5SDimitry Andricpublic: 1683*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1684*0b57cec5SDimitry Andric ~promise(); 1685*0b57cec5SDimitry Andric 1686*0b57cec5SDimitry Andric // assignment 1687*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1688*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1689*0b57cec5SDimitry Andric promise& operator=(promise&& __rhs) _NOEXCEPT 1690*0b57cec5SDimitry Andric { 1691*0b57cec5SDimitry Andric promise(std::move(__rhs)).swap(*this); 1692*0b57cec5SDimitry Andric return *this; 1693*0b57cec5SDimitry Andric } 1694*0b57cec5SDimitry Andric promise& operator=(const promise& __rhs) = delete; 1695*0b57cec5SDimitry Andric#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1696*0b57cec5SDimitry Andricprivate: 1697*0b57cec5SDimitry Andric promise& operator=(const promise& __rhs); 1698*0b57cec5SDimitry Andricpublic: 1699*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1700*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1701*0b57cec5SDimitry Andric void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1702*0b57cec5SDimitry Andric 1703*0b57cec5SDimitry Andric // retrieving the result 1704*0b57cec5SDimitry Andric future<void> get_future(); 1705*0b57cec5SDimitry Andric 1706*0b57cec5SDimitry Andric // setting the result 1707*0b57cec5SDimitry Andric void set_value(); 1708*0b57cec5SDimitry Andric void set_exception(exception_ptr __p); 1709*0b57cec5SDimitry Andric 1710*0b57cec5SDimitry Andric // setting the result with deferred notification 1711*0b57cec5SDimitry Andric void set_value_at_thread_exit(); 1712*0b57cec5SDimitry Andric void set_exception_at_thread_exit(exception_ptr __p); 1713*0b57cec5SDimitry Andric}; 1714*0b57cec5SDimitry Andric 1715*0b57cec5SDimitry Andrictemplate <class _Alloc> 1716*0b57cec5SDimitry Andricpromise<void>::promise(allocator_arg_t, const _Alloc& __a0) 1717*0b57cec5SDimitry Andric{ 1718*0b57cec5SDimitry Andric typedef __assoc_sub_state_alloc<_Alloc> _State; 1719*0b57cec5SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; 1720*0b57cec5SDimitry Andric typedef __allocator_destructor<_A2> _D2; 1721*0b57cec5SDimitry Andric _A2 __a(__a0); 1722*0b57cec5SDimitry Andric unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1723*0b57cec5SDimitry Andric ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0); 1724*0b57cec5SDimitry Andric __state_ = _VSTD::addressof(*__hold.release()); 1725*0b57cec5SDimitry Andric} 1726*0b57cec5SDimitry Andric 1727*0b57cec5SDimitry Andrictemplate <class _Rp> 1728*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 1729*0b57cec5SDimitry Andricvoid 1730*0b57cec5SDimitry Andricswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT 1731*0b57cec5SDimitry Andric{ 1732*0b57cec5SDimitry Andric __x.swap(__y); 1733*0b57cec5SDimitry Andric} 1734*0b57cec5SDimitry Andric 1735*0b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc> 1736*0b57cec5SDimitry Andric struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc> 1737*0b57cec5SDimitry Andric : public true_type {}; 1738*0b57cec5SDimitry Andric 1739*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS 1740*0b57cec5SDimitry Andric 1741*0b57cec5SDimitry Andric// packaged_task 1742*0b57cec5SDimitry Andric 1743*0b57cec5SDimitry Andrictemplate<class _Fp> class __packaged_task_base; 1744*0b57cec5SDimitry Andric 1745*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 1746*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)> 1747*0b57cec5SDimitry Andric{ 1748*0b57cec5SDimitry Andric __packaged_task_base(const __packaged_task_base&); 1749*0b57cec5SDimitry Andric __packaged_task_base& operator=(const __packaged_task_base&); 1750*0b57cec5SDimitry Andricpublic: 1751*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1752*0b57cec5SDimitry Andric __packaged_task_base() {} 1753*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1754*0b57cec5SDimitry Andric virtual ~__packaged_task_base() {} 1755*0b57cec5SDimitry Andric virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0; 1756*0b57cec5SDimitry Andric virtual void destroy() = 0; 1757*0b57cec5SDimitry Andric virtual void destroy_deallocate() = 0; 1758*0b57cec5SDimitry Andric virtual _Rp operator()(_ArgTypes&& ...) = 0; 1759*0b57cec5SDimitry Andric}; 1760*0b57cec5SDimitry Andric 1761*0b57cec5SDimitry Andrictemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func; 1762*0b57cec5SDimitry Andric 1763*0b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1764*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> 1765*0b57cec5SDimitry Andric : public __packaged_task_base<_Rp(_ArgTypes...)> 1766*0b57cec5SDimitry Andric{ 1767*0b57cec5SDimitry Andric __compressed_pair<_Fp, _Alloc> __f_; 1768*0b57cec5SDimitry Andricpublic: 1769*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1770*0b57cec5SDimitry Andric explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {} 1771*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1772*0b57cec5SDimitry Andric explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {} 1773*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1774*0b57cec5SDimitry Andric __packaged_task_func(const _Fp& __f, const _Alloc& __a) 1775*0b57cec5SDimitry Andric : __f_(__f, __a) {} 1776*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1777*0b57cec5SDimitry Andric __packaged_task_func(_Fp&& __f, const _Alloc& __a) 1778*0b57cec5SDimitry Andric : __f_(_VSTD::move(__f), __a) {} 1779*0b57cec5SDimitry Andric virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; 1780*0b57cec5SDimitry Andric virtual void destroy(); 1781*0b57cec5SDimitry Andric virtual void destroy_deallocate(); 1782*0b57cec5SDimitry Andric virtual _Rp operator()(_ArgTypes&& ... __args); 1783*0b57cec5SDimitry Andric}; 1784*0b57cec5SDimitry Andric 1785*0b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1786*0b57cec5SDimitry Andricvoid 1787*0b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to( 1788*0b57cec5SDimitry Andric __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT 1789*0b57cec5SDimitry Andric{ 1790*0b57cec5SDimitry Andric ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second())); 1791*0b57cec5SDimitry Andric} 1792*0b57cec5SDimitry Andric 1793*0b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1794*0b57cec5SDimitry Andricvoid 1795*0b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() 1796*0b57cec5SDimitry Andric{ 1797*0b57cec5SDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1798*0b57cec5SDimitry Andric} 1799*0b57cec5SDimitry Andric 1800*0b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1801*0b57cec5SDimitry Andricvoid 1802*0b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() 1803*0b57cec5SDimitry Andric{ 1804*0b57cec5SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap; 1805*0b57cec5SDimitry Andric typedef allocator_traits<_Ap> _ATraits; 1806*0b57cec5SDimitry Andric typedef pointer_traits<typename _ATraits::pointer> _PTraits; 1807*0b57cec5SDimitry Andric _Ap __a(__f_.second()); 1808*0b57cec5SDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1809*0b57cec5SDimitry Andric __a.deallocate(_PTraits::pointer_to(*this), 1); 1810*0b57cec5SDimitry Andric} 1811*0b57cec5SDimitry Andric 1812*0b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1813*0b57cec5SDimitry Andric_Rp 1814*0b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) 1815*0b57cec5SDimitry Andric{ 1816*0b57cec5SDimitry Andric return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); 1817*0b57cec5SDimitry Andric} 1818*0b57cec5SDimitry Andric 1819*0b57cec5SDimitry Andrictemplate <class _Callable> class __packaged_task_function; 1820*0b57cec5SDimitry Andric 1821*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 1822*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)> 1823*0b57cec5SDimitry Andric{ 1824*0b57cec5SDimitry Andric typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; 1825*0b57cec5SDimitry Andric typename aligned_storage<3*sizeof(void*)>::type __buf_; 1826*0b57cec5SDimitry Andric __base* __f_; 1827*0b57cec5SDimitry Andric 1828*0b57cec5SDimitry Andricpublic: 1829*0b57cec5SDimitry Andric typedef _Rp result_type; 1830*0b57cec5SDimitry Andric 1831*0b57cec5SDimitry Andric // construct/copy/destroy: 1832*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1833*0b57cec5SDimitry Andric __packaged_task_function() _NOEXCEPT : __f_(nullptr) {} 1834*0b57cec5SDimitry Andric template<class _Fp> 1835*0b57cec5SDimitry Andric __packaged_task_function(_Fp&& __f); 1836*0b57cec5SDimitry Andric template<class _Fp, class _Alloc> 1837*0b57cec5SDimitry Andric __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); 1838*0b57cec5SDimitry Andric 1839*0b57cec5SDimitry Andric __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; 1840*0b57cec5SDimitry Andric __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; 1841*0b57cec5SDimitry Andric 1842*0b57cec5SDimitry Andric __packaged_task_function(const __packaged_task_function&) = delete; 1843*0b57cec5SDimitry Andric __packaged_task_function& operator=(const __packaged_task_function&) = delete; 1844*0b57cec5SDimitry Andric 1845*0b57cec5SDimitry Andric ~__packaged_task_function(); 1846*0b57cec5SDimitry Andric 1847*0b57cec5SDimitry Andric void swap(__packaged_task_function&) _NOEXCEPT; 1848*0b57cec5SDimitry Andric 1849*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1850*0b57cec5SDimitry Andric _Rp operator()(_ArgTypes...) const; 1851*0b57cec5SDimitry Andric}; 1852*0b57cec5SDimitry Andric 1853*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 1854*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT 1855*0b57cec5SDimitry Andric{ 1856*0b57cec5SDimitry Andric if (__f.__f_ == nullptr) 1857*0b57cec5SDimitry Andric __f_ = nullptr; 1858*0b57cec5SDimitry Andric else if (__f.__f_ == (__base*)&__f.__buf_) 1859*0b57cec5SDimitry Andric { 1860*0b57cec5SDimitry Andric __f_ = (__base*)&__buf_; 1861*0b57cec5SDimitry Andric __f.__f_->__move_to(__f_); 1862*0b57cec5SDimitry Andric } 1863*0b57cec5SDimitry Andric else 1864*0b57cec5SDimitry Andric { 1865*0b57cec5SDimitry Andric __f_ = __f.__f_; 1866*0b57cec5SDimitry Andric __f.__f_ = nullptr; 1867*0b57cec5SDimitry Andric } 1868*0b57cec5SDimitry Andric} 1869*0b57cec5SDimitry Andric 1870*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 1871*0b57cec5SDimitry Andrictemplate <class _Fp> 1872*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) 1873*0b57cec5SDimitry Andric : __f_(nullptr) 1874*0b57cec5SDimitry Andric{ 1875*0b57cec5SDimitry Andric typedef typename remove_reference<typename decay<_Fp>::type>::type _FR; 1876*0b57cec5SDimitry Andric typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; 1877*0b57cec5SDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) 1878*0b57cec5SDimitry Andric { 1879*0b57cec5SDimitry Andric __f_ = (__base*)&__buf_; 1880*0b57cec5SDimitry Andric ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); 1881*0b57cec5SDimitry Andric } 1882*0b57cec5SDimitry Andric else 1883*0b57cec5SDimitry Andric { 1884*0b57cec5SDimitry Andric typedef allocator<_FF> _Ap; 1885*0b57cec5SDimitry Andric _Ap __a; 1886*0b57cec5SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 1887*0b57cec5SDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1888*0b57cec5SDimitry Andric ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a)); 1889*0b57cec5SDimitry Andric __f_ = __hold.release(); 1890*0b57cec5SDimitry Andric } 1891*0b57cec5SDimitry Andric} 1892*0b57cec5SDimitry Andric 1893*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 1894*0b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc> 1895*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function( 1896*0b57cec5SDimitry Andric allocator_arg_t, const _Alloc& __a0, _Fp&& __f) 1897*0b57cec5SDimitry Andric : __f_(nullptr) 1898*0b57cec5SDimitry Andric{ 1899*0b57cec5SDimitry Andric typedef typename remove_reference<typename decay<_Fp>::type>::type _FR; 1900*0b57cec5SDimitry Andric typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; 1901*0b57cec5SDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) 1902*0b57cec5SDimitry Andric { 1903*0b57cec5SDimitry Andric __f_ = (__base*)&__buf_; 1904*0b57cec5SDimitry Andric ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); 1905*0b57cec5SDimitry Andric } 1906*0b57cec5SDimitry Andric else 1907*0b57cec5SDimitry Andric { 1908*0b57cec5SDimitry Andric typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap; 1909*0b57cec5SDimitry Andric _Ap __a(__a0); 1910*0b57cec5SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 1911*0b57cec5SDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1912*0b57cec5SDimitry Andric ::new (static_cast<void*>(_VSTD::addressof(*__hold.get()))) 1913*0b57cec5SDimitry Andric _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a)); 1914*0b57cec5SDimitry Andric __f_ = _VSTD::addressof(*__hold.release()); 1915*0b57cec5SDimitry Andric } 1916*0b57cec5SDimitry Andric} 1917*0b57cec5SDimitry Andric 1918*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 1919*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>& 1920*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT 1921*0b57cec5SDimitry Andric{ 1922*0b57cec5SDimitry Andric if (__f_ == (__base*)&__buf_) 1923*0b57cec5SDimitry Andric __f_->destroy(); 1924*0b57cec5SDimitry Andric else if (__f_) 1925*0b57cec5SDimitry Andric __f_->destroy_deallocate(); 1926*0b57cec5SDimitry Andric __f_ = nullptr; 1927*0b57cec5SDimitry Andric if (__f.__f_ == nullptr) 1928*0b57cec5SDimitry Andric __f_ = nullptr; 1929*0b57cec5SDimitry Andric else if (__f.__f_ == (__base*)&__f.__buf_) 1930*0b57cec5SDimitry Andric { 1931*0b57cec5SDimitry Andric __f_ = (__base*)&__buf_; 1932*0b57cec5SDimitry Andric __f.__f_->__move_to(__f_); 1933*0b57cec5SDimitry Andric } 1934*0b57cec5SDimitry Andric else 1935*0b57cec5SDimitry Andric { 1936*0b57cec5SDimitry Andric __f_ = __f.__f_; 1937*0b57cec5SDimitry Andric __f.__f_ = nullptr; 1938*0b57cec5SDimitry Andric } 1939*0b57cec5SDimitry Andric return *this; 1940*0b57cec5SDimitry Andric} 1941*0b57cec5SDimitry Andric 1942*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 1943*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() 1944*0b57cec5SDimitry Andric{ 1945*0b57cec5SDimitry Andric if (__f_ == (__base*)&__buf_) 1946*0b57cec5SDimitry Andric __f_->destroy(); 1947*0b57cec5SDimitry Andric else if (__f_) 1948*0b57cec5SDimitry Andric __f_->destroy_deallocate(); 1949*0b57cec5SDimitry Andric} 1950*0b57cec5SDimitry Andric 1951*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 1952*0b57cec5SDimitry Andricvoid 1953*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT 1954*0b57cec5SDimitry Andric{ 1955*0b57cec5SDimitry Andric if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 1956*0b57cec5SDimitry Andric { 1957*0b57cec5SDimitry Andric typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 1958*0b57cec5SDimitry Andric __base* __t = (__base*)&__tempbuf; 1959*0b57cec5SDimitry Andric __f_->__move_to(__t); 1960*0b57cec5SDimitry Andric __f_->destroy(); 1961*0b57cec5SDimitry Andric __f_ = nullptr; 1962*0b57cec5SDimitry Andric __f.__f_->__move_to((__base*)&__buf_); 1963*0b57cec5SDimitry Andric __f.__f_->destroy(); 1964*0b57cec5SDimitry Andric __f.__f_ = nullptr; 1965*0b57cec5SDimitry Andric __f_ = (__base*)&__buf_; 1966*0b57cec5SDimitry Andric __t->__move_to((__base*)&__f.__buf_); 1967*0b57cec5SDimitry Andric __t->destroy(); 1968*0b57cec5SDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 1969*0b57cec5SDimitry Andric } 1970*0b57cec5SDimitry Andric else if (__f_ == (__base*)&__buf_) 1971*0b57cec5SDimitry Andric { 1972*0b57cec5SDimitry Andric __f_->__move_to((__base*)&__f.__buf_); 1973*0b57cec5SDimitry Andric __f_->destroy(); 1974*0b57cec5SDimitry Andric __f_ = __f.__f_; 1975*0b57cec5SDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 1976*0b57cec5SDimitry Andric } 1977*0b57cec5SDimitry Andric else if (__f.__f_ == (__base*)&__f.__buf_) 1978*0b57cec5SDimitry Andric { 1979*0b57cec5SDimitry Andric __f.__f_->__move_to((__base*)&__buf_); 1980*0b57cec5SDimitry Andric __f.__f_->destroy(); 1981*0b57cec5SDimitry Andric __f.__f_ = __f_; 1982*0b57cec5SDimitry Andric __f_ = (__base*)&__buf_; 1983*0b57cec5SDimitry Andric } 1984*0b57cec5SDimitry Andric else 1985*0b57cec5SDimitry Andric _VSTD::swap(__f_, __f.__f_); 1986*0b57cec5SDimitry Andric} 1987*0b57cec5SDimitry Andric 1988*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 1989*0b57cec5SDimitry Andricinline 1990*0b57cec5SDimitry Andric_Rp 1991*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const 1992*0b57cec5SDimitry Andric{ 1993*0b57cec5SDimitry Andric return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); 1994*0b57cec5SDimitry Andric} 1995*0b57cec5SDimitry Andric 1996*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 1997*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)> 1998*0b57cec5SDimitry Andric{ 1999*0b57cec5SDimitry Andricpublic: 2000*0b57cec5SDimitry Andric typedef _Rp result_type; // extension 2001*0b57cec5SDimitry Andric 2002*0b57cec5SDimitry Andricprivate: 2003*0b57cec5SDimitry Andric __packaged_task_function<result_type(_ArgTypes...)> __f_; 2004*0b57cec5SDimitry Andric promise<result_type> __p_; 2005*0b57cec5SDimitry Andric 2006*0b57cec5SDimitry Andricpublic: 2007*0b57cec5SDimitry Andric // construction and destruction 2008*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2009*0b57cec5SDimitry Andric packaged_task() _NOEXCEPT : __p_(nullptr) {} 2010*0b57cec5SDimitry Andric template <class _Fp, 2011*0b57cec5SDimitry Andric class = typename enable_if 2012*0b57cec5SDimitry Andric < 2013*0b57cec5SDimitry Andric !is_same< 2014*0b57cec5SDimitry Andric typename __uncvref<_Fp>::type, 2015*0b57cec5SDimitry Andric packaged_task 2016*0b57cec5SDimitry Andric >::value 2017*0b57cec5SDimitry Andric >::type 2018*0b57cec5SDimitry Andric > 2019*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2020*0b57cec5SDimitry Andric explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} 2021*0b57cec5SDimitry Andric template <class _Fp, class _Allocator, 2022*0b57cec5SDimitry Andric class = typename enable_if 2023*0b57cec5SDimitry Andric < 2024*0b57cec5SDimitry Andric !is_same< 2025*0b57cec5SDimitry Andric typename __uncvref<_Fp>::type, 2026*0b57cec5SDimitry Andric packaged_task 2027*0b57cec5SDimitry Andric >::value 2028*0b57cec5SDimitry Andric >::type 2029*0b57cec5SDimitry Andric > 2030*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2031*0b57cec5SDimitry Andric packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 2032*0b57cec5SDimitry Andric : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), 2033*0b57cec5SDimitry Andric __p_(allocator_arg, __a) {} 2034*0b57cec5SDimitry Andric // ~packaged_task() = default; 2035*0b57cec5SDimitry Andric 2036*0b57cec5SDimitry Andric // no copy 2037*0b57cec5SDimitry Andric packaged_task(const packaged_task&) = delete; 2038*0b57cec5SDimitry Andric packaged_task& operator=(const packaged_task&) = delete; 2039*0b57cec5SDimitry Andric 2040*0b57cec5SDimitry Andric // move support 2041*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2042*0b57cec5SDimitry Andric packaged_task(packaged_task&& __other) _NOEXCEPT 2043*0b57cec5SDimitry Andric : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 2044*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2045*0b57cec5SDimitry Andric packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 2046*0b57cec5SDimitry Andric { 2047*0b57cec5SDimitry Andric __f_ = _VSTD::move(__other.__f_); 2048*0b57cec5SDimitry Andric __p_ = _VSTD::move(__other.__p_); 2049*0b57cec5SDimitry Andric return *this; 2050*0b57cec5SDimitry Andric } 2051*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2052*0b57cec5SDimitry Andric void swap(packaged_task& __other) _NOEXCEPT 2053*0b57cec5SDimitry Andric { 2054*0b57cec5SDimitry Andric __f_.swap(__other.__f_); 2055*0b57cec5SDimitry Andric __p_.swap(__other.__p_); 2056*0b57cec5SDimitry Andric } 2057*0b57cec5SDimitry Andric 2058*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2059*0b57cec5SDimitry Andric bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} 2060*0b57cec5SDimitry Andric 2061*0b57cec5SDimitry Andric // result retrieval 2062*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2063*0b57cec5SDimitry Andric future<result_type> get_future() {return __p_.get_future();} 2064*0b57cec5SDimitry Andric 2065*0b57cec5SDimitry Andric // execution 2066*0b57cec5SDimitry Andric void operator()(_ArgTypes... __args); 2067*0b57cec5SDimitry Andric void make_ready_at_thread_exit(_ArgTypes... __args); 2068*0b57cec5SDimitry Andric 2069*0b57cec5SDimitry Andric void reset(); 2070*0b57cec5SDimitry Andric}; 2071*0b57cec5SDimitry Andric 2072*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 2073*0b57cec5SDimitry Andricvoid 2074*0b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) 2075*0b57cec5SDimitry Andric{ 2076*0b57cec5SDimitry Andric if (__p_.__state_ == nullptr) 2077*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 2078*0b57cec5SDimitry Andric if (__p_.__state_->__has_value()) 2079*0b57cec5SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 2080*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2081*0b57cec5SDimitry Andric try 2082*0b57cec5SDimitry Andric { 2083*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 2084*0b57cec5SDimitry Andric __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...)); 2085*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2086*0b57cec5SDimitry Andric } 2087*0b57cec5SDimitry Andric catch (...) 2088*0b57cec5SDimitry Andric { 2089*0b57cec5SDimitry Andric __p_.set_exception(current_exception()); 2090*0b57cec5SDimitry Andric } 2091*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 2092*0b57cec5SDimitry Andric} 2093*0b57cec5SDimitry Andric 2094*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 2095*0b57cec5SDimitry Andricvoid 2096*0b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) 2097*0b57cec5SDimitry Andric{ 2098*0b57cec5SDimitry Andric if (__p_.__state_ == nullptr) 2099*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 2100*0b57cec5SDimitry Andric if (__p_.__state_->__has_value()) 2101*0b57cec5SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 2102*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2103*0b57cec5SDimitry Andric try 2104*0b57cec5SDimitry Andric { 2105*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 2106*0b57cec5SDimitry Andric __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...)); 2107*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2108*0b57cec5SDimitry Andric } 2109*0b57cec5SDimitry Andric catch (...) 2110*0b57cec5SDimitry Andric { 2111*0b57cec5SDimitry Andric __p_.set_exception_at_thread_exit(current_exception()); 2112*0b57cec5SDimitry Andric } 2113*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 2114*0b57cec5SDimitry Andric} 2115*0b57cec5SDimitry Andric 2116*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes> 2117*0b57cec5SDimitry Andricvoid 2118*0b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::reset() 2119*0b57cec5SDimitry Andric{ 2120*0b57cec5SDimitry Andric if (!valid()) 2121*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 2122*0b57cec5SDimitry Andric __p_ = promise<result_type>(); 2123*0b57cec5SDimitry Andric} 2124*0b57cec5SDimitry Andric 2125*0b57cec5SDimitry Andrictemplate<class ..._ArgTypes> 2126*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)> 2127*0b57cec5SDimitry Andric{ 2128*0b57cec5SDimitry Andricpublic: 2129*0b57cec5SDimitry Andric typedef void result_type; // extension 2130*0b57cec5SDimitry Andric 2131*0b57cec5SDimitry Andricprivate: 2132*0b57cec5SDimitry Andric __packaged_task_function<result_type(_ArgTypes...)> __f_; 2133*0b57cec5SDimitry Andric promise<result_type> __p_; 2134*0b57cec5SDimitry Andric 2135*0b57cec5SDimitry Andricpublic: 2136*0b57cec5SDimitry Andric // construction and destruction 2137*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2138*0b57cec5SDimitry Andric packaged_task() _NOEXCEPT : __p_(nullptr) {} 2139*0b57cec5SDimitry Andric template <class _Fp, 2140*0b57cec5SDimitry Andric class = typename enable_if 2141*0b57cec5SDimitry Andric < 2142*0b57cec5SDimitry Andric !is_same< 2143*0b57cec5SDimitry Andric typename __uncvref<_Fp>::type, 2144*0b57cec5SDimitry Andric packaged_task 2145*0b57cec5SDimitry Andric >::value 2146*0b57cec5SDimitry Andric >::type 2147*0b57cec5SDimitry Andric > 2148*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2149*0b57cec5SDimitry Andric explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} 2150*0b57cec5SDimitry Andric template <class _Fp, class _Allocator, 2151*0b57cec5SDimitry Andric class = typename enable_if 2152*0b57cec5SDimitry Andric < 2153*0b57cec5SDimitry Andric !is_same< 2154*0b57cec5SDimitry Andric typename __uncvref<_Fp>::type, 2155*0b57cec5SDimitry Andric packaged_task 2156*0b57cec5SDimitry Andric >::value 2157*0b57cec5SDimitry Andric >::type 2158*0b57cec5SDimitry Andric > 2159*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2160*0b57cec5SDimitry Andric packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 2161*0b57cec5SDimitry Andric : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), 2162*0b57cec5SDimitry Andric __p_(allocator_arg, __a) {} 2163*0b57cec5SDimitry Andric // ~packaged_task() = default; 2164*0b57cec5SDimitry Andric 2165*0b57cec5SDimitry Andric // no copy 2166*0b57cec5SDimitry Andric packaged_task(const packaged_task&) = delete; 2167*0b57cec5SDimitry Andric packaged_task& operator=(const packaged_task&) = delete; 2168*0b57cec5SDimitry Andric 2169*0b57cec5SDimitry Andric // move support 2170*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2171*0b57cec5SDimitry Andric packaged_task(packaged_task&& __other) _NOEXCEPT 2172*0b57cec5SDimitry Andric : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 2173*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2174*0b57cec5SDimitry Andric packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 2175*0b57cec5SDimitry Andric { 2176*0b57cec5SDimitry Andric __f_ = _VSTD::move(__other.__f_); 2177*0b57cec5SDimitry Andric __p_ = _VSTD::move(__other.__p_); 2178*0b57cec5SDimitry Andric return *this; 2179*0b57cec5SDimitry Andric } 2180*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2181*0b57cec5SDimitry Andric void swap(packaged_task& __other) _NOEXCEPT 2182*0b57cec5SDimitry Andric { 2183*0b57cec5SDimitry Andric __f_.swap(__other.__f_); 2184*0b57cec5SDimitry Andric __p_.swap(__other.__p_); 2185*0b57cec5SDimitry Andric } 2186*0b57cec5SDimitry Andric 2187*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2188*0b57cec5SDimitry Andric bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} 2189*0b57cec5SDimitry Andric 2190*0b57cec5SDimitry Andric // result retrieval 2191*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2192*0b57cec5SDimitry Andric future<result_type> get_future() {return __p_.get_future();} 2193*0b57cec5SDimitry Andric 2194*0b57cec5SDimitry Andric // execution 2195*0b57cec5SDimitry Andric void operator()(_ArgTypes... __args); 2196*0b57cec5SDimitry Andric void make_ready_at_thread_exit(_ArgTypes... __args); 2197*0b57cec5SDimitry Andric 2198*0b57cec5SDimitry Andric void reset(); 2199*0b57cec5SDimitry Andric}; 2200*0b57cec5SDimitry Andric 2201*0b57cec5SDimitry Andrictemplate<class ..._ArgTypes> 2202*0b57cec5SDimitry Andricvoid 2203*0b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) 2204*0b57cec5SDimitry Andric{ 2205*0b57cec5SDimitry Andric if (__p_.__state_ == nullptr) 2206*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 2207*0b57cec5SDimitry Andric if (__p_.__state_->__has_value()) 2208*0b57cec5SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 2209*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2210*0b57cec5SDimitry Andric try 2211*0b57cec5SDimitry Andric { 2212*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 2213*0b57cec5SDimitry Andric __f_(_VSTD::forward<_ArgTypes>(__args)...); 2214*0b57cec5SDimitry Andric __p_.set_value(); 2215*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2216*0b57cec5SDimitry Andric } 2217*0b57cec5SDimitry Andric catch (...) 2218*0b57cec5SDimitry Andric { 2219*0b57cec5SDimitry Andric __p_.set_exception(current_exception()); 2220*0b57cec5SDimitry Andric } 2221*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 2222*0b57cec5SDimitry Andric} 2223*0b57cec5SDimitry Andric 2224*0b57cec5SDimitry Andrictemplate<class ..._ArgTypes> 2225*0b57cec5SDimitry Andricvoid 2226*0b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) 2227*0b57cec5SDimitry Andric{ 2228*0b57cec5SDimitry Andric if (__p_.__state_ == nullptr) 2229*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 2230*0b57cec5SDimitry Andric if (__p_.__state_->__has_value()) 2231*0b57cec5SDimitry Andric __throw_future_error(future_errc::promise_already_satisfied); 2232*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2233*0b57cec5SDimitry Andric try 2234*0b57cec5SDimitry Andric { 2235*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 2236*0b57cec5SDimitry Andric __f_(_VSTD::forward<_ArgTypes>(__args)...); 2237*0b57cec5SDimitry Andric __p_.set_value_at_thread_exit(); 2238*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2239*0b57cec5SDimitry Andric } 2240*0b57cec5SDimitry Andric catch (...) 2241*0b57cec5SDimitry Andric { 2242*0b57cec5SDimitry Andric __p_.set_exception_at_thread_exit(current_exception()); 2243*0b57cec5SDimitry Andric } 2244*0b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS 2245*0b57cec5SDimitry Andric} 2246*0b57cec5SDimitry Andric 2247*0b57cec5SDimitry Andrictemplate<class ..._ArgTypes> 2248*0b57cec5SDimitry Andricvoid 2249*0b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::reset() 2250*0b57cec5SDimitry Andric{ 2251*0b57cec5SDimitry Andric if (!valid()) 2252*0b57cec5SDimitry Andric __throw_future_error(future_errc::no_state); 2253*0b57cec5SDimitry Andric __p_ = promise<result_type>(); 2254*0b57cec5SDimitry Andric} 2255*0b57cec5SDimitry Andric 2256*0b57cec5SDimitry Andrictemplate <class _Callable> 2257*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2258*0b57cec5SDimitry Andricvoid 2259*0b57cec5SDimitry Andricswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT 2260*0b57cec5SDimitry Andric{ 2261*0b57cec5SDimitry Andric __x.swap(__y); 2262*0b57cec5SDimitry Andric} 2263*0b57cec5SDimitry Andric 2264*0b57cec5SDimitry Andrictemplate <class _Callable, class _Alloc> 2265*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc> 2266*0b57cec5SDimitry Andric : public true_type {}; 2267*0b57cec5SDimitry Andric 2268*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 2269*0b57cec5SDimitry Andricfuture<_Rp> 2270*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2271*0b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp&& __f) 2272*0b57cec5SDimitry Andric#else 2273*0b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp __f) 2274*0b57cec5SDimitry Andric#endif 2275*0b57cec5SDimitry Andric{ 2276*0b57cec5SDimitry Andric unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> 2277*0b57cec5SDimitry Andric __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); 2278*0b57cec5SDimitry Andric return future<_Rp>(__h.get()); 2279*0b57cec5SDimitry Andric} 2280*0b57cec5SDimitry Andric 2281*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp> 2282*0b57cec5SDimitry Andricfuture<_Rp> 2283*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2284*0b57cec5SDimitry Andric__make_async_assoc_state(_Fp&& __f) 2285*0b57cec5SDimitry Andric#else 2286*0b57cec5SDimitry Andric__make_async_assoc_state(_Fp __f) 2287*0b57cec5SDimitry Andric#endif 2288*0b57cec5SDimitry Andric{ 2289*0b57cec5SDimitry Andric unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> 2290*0b57cec5SDimitry Andric __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); 2291*0b57cec5SDimitry Andric _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach(); 2292*0b57cec5SDimitry Andric return future<_Rp>(__h.get()); 2293*0b57cec5SDimitry Andric} 2294*0b57cec5SDimitry Andric 2295*0b57cec5SDimitry Andrictemplate <class _Fp, class... _Args> 2296*0b57cec5SDimitry Andricclass __async_func 2297*0b57cec5SDimitry Andric{ 2298*0b57cec5SDimitry Andric tuple<_Fp, _Args...> __f_; 2299*0b57cec5SDimitry Andric 2300*0b57cec5SDimitry Andricpublic: 2301*0b57cec5SDimitry Andric typedef typename __invoke_of<_Fp, _Args...>::type _Rp; 2302*0b57cec5SDimitry Andric 2303*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2304*0b57cec5SDimitry Andric explicit __async_func(_Fp&& __f, _Args&&... __args) 2305*0b57cec5SDimitry Andric : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {} 2306*0b57cec5SDimitry Andric 2307*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2308*0b57cec5SDimitry Andric __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {} 2309*0b57cec5SDimitry Andric 2310*0b57cec5SDimitry Andric _Rp operator()() 2311*0b57cec5SDimitry Andric { 2312*0b57cec5SDimitry Andric typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index; 2313*0b57cec5SDimitry Andric return __execute(_Index()); 2314*0b57cec5SDimitry Andric } 2315*0b57cec5SDimitry Andricprivate: 2316*0b57cec5SDimitry Andric template <size_t ..._Indices> 2317*0b57cec5SDimitry Andric _Rp 2318*0b57cec5SDimitry Andric __execute(__tuple_indices<_Indices...>) 2319*0b57cec5SDimitry Andric { 2320*0b57cec5SDimitry Andric return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); 2321*0b57cec5SDimitry Andric } 2322*0b57cec5SDimitry Andric}; 2323*0b57cec5SDimitry Andric 2324*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value ) 2325*0b57cec5SDimitry Andric{ return (int(__policy) & int(__value)) != 0; } 2326*0b57cec5SDimitry Andric 2327*0b57cec5SDimitry Andrictemplate <class _Fp, class... _Args> 2328*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 2329*0b57cec5SDimitry Andricfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> 2330*0b57cec5SDimitry Andricasync(launch __policy, _Fp&& __f, _Args&&... __args) 2331*0b57cec5SDimitry Andric{ 2332*0b57cec5SDimitry Andric typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF; 2333*0b57cec5SDimitry Andric typedef typename _BF::_Rp _Rp; 2334*0b57cec5SDimitry Andric 2335*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2336*0b57cec5SDimitry Andric try 2337*0b57cec5SDimitry Andric { 2338*0b57cec5SDimitry Andric#endif 2339*0b57cec5SDimitry Andric if (__does_policy_contain(__policy, launch::async)) 2340*0b57cec5SDimitry Andric return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), 2341*0b57cec5SDimitry Andric __decay_copy(_VSTD::forward<_Args>(__args))...)); 2342*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2343*0b57cec5SDimitry Andric } 2344*0b57cec5SDimitry Andric catch ( ... ) { if (__policy == launch::async) throw ; } 2345*0b57cec5SDimitry Andric#endif 2346*0b57cec5SDimitry Andric 2347*0b57cec5SDimitry Andric if (__does_policy_contain(__policy, launch::deferred)) 2348*0b57cec5SDimitry Andric return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), 2349*0b57cec5SDimitry Andric __decay_copy(_VSTD::forward<_Args>(__args))...)); 2350*0b57cec5SDimitry Andric return future<_Rp>{}; 2351*0b57cec5SDimitry Andric} 2352*0b57cec5SDimitry Andric 2353*0b57cec5SDimitry Andrictemplate <class _Fp, class... _Args> 2354*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY 2355*0b57cec5SDimitry Andricfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> 2356*0b57cec5SDimitry Andricasync(_Fp&& __f, _Args&&... __args) 2357*0b57cec5SDimitry Andric{ 2358*0b57cec5SDimitry Andric return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f), 2359*0b57cec5SDimitry Andric _VSTD::forward<_Args>(__args)...); 2360*0b57cec5SDimitry Andric} 2361*0b57cec5SDimitry Andric 2362*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_VARIADICS 2363*0b57cec5SDimitry Andric 2364*0b57cec5SDimitry Andric// shared_future 2365*0b57cec5SDimitry Andric 2366*0b57cec5SDimitry Andrictemplate <class _Rp> 2367*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future 2368*0b57cec5SDimitry Andric{ 2369*0b57cec5SDimitry Andric __assoc_state<_Rp>* __state_; 2370*0b57cec5SDimitry Andric 2371*0b57cec5SDimitry Andricpublic: 2372*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2373*0b57cec5SDimitry Andric shared_future() _NOEXCEPT : __state_(nullptr) {} 2374*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2375*0b57cec5SDimitry Andric shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 2376*0b57cec5SDimitry Andric {if (__state_) __state_->__add_shared();} 2377*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2378*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2379*0b57cec5SDimitry Andric shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) 2380*0b57cec5SDimitry Andric {__f.__state_ = nullptr;} 2381*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2382*0b57cec5SDimitry Andric shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 2383*0b57cec5SDimitry Andric {__rhs.__state_ = nullptr;} 2384*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2385*0b57cec5SDimitry Andric ~shared_future(); 2386*0b57cec5SDimitry Andric shared_future& operator=(const shared_future& __rhs) _NOEXCEPT; 2387*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2388*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2389*0b57cec5SDimitry Andric shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 2390*0b57cec5SDimitry Andric { 2391*0b57cec5SDimitry Andric shared_future(std::move(__rhs)).swap(*this); 2392*0b57cec5SDimitry Andric return *this; 2393*0b57cec5SDimitry Andric } 2394*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2395*0b57cec5SDimitry Andric 2396*0b57cec5SDimitry Andric // retrieving the value 2397*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2398*0b57cec5SDimitry Andric const _Rp& get() const {return __state_->copy();} 2399*0b57cec5SDimitry Andric 2400*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2401*0b57cec5SDimitry Andric void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2402*0b57cec5SDimitry Andric 2403*0b57cec5SDimitry Andric // functions to check state 2404*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2405*0b57cec5SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 2406*0b57cec5SDimitry Andric 2407*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2408*0b57cec5SDimitry Andric void wait() const {__state_->wait();} 2409*0b57cec5SDimitry Andric template <class _Rep, class _Period> 2410*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2411*0b57cec5SDimitry Andric future_status 2412*0b57cec5SDimitry Andric wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 2413*0b57cec5SDimitry Andric {return __state_->wait_for(__rel_time);} 2414*0b57cec5SDimitry Andric template <class _Clock, class _Duration> 2415*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2416*0b57cec5SDimitry Andric future_status 2417*0b57cec5SDimitry Andric wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 2418*0b57cec5SDimitry Andric {return __state_->wait_until(__abs_time);} 2419*0b57cec5SDimitry Andric}; 2420*0b57cec5SDimitry Andric 2421*0b57cec5SDimitry Andrictemplate <class _Rp> 2422*0b57cec5SDimitry Andricshared_future<_Rp>::~shared_future() 2423*0b57cec5SDimitry Andric{ 2424*0b57cec5SDimitry Andric if (__state_) 2425*0b57cec5SDimitry Andric __state_->__release_shared(); 2426*0b57cec5SDimitry Andric} 2427*0b57cec5SDimitry Andric 2428*0b57cec5SDimitry Andrictemplate <class _Rp> 2429*0b57cec5SDimitry Andricshared_future<_Rp>& 2430*0b57cec5SDimitry Andricshared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT 2431*0b57cec5SDimitry Andric{ 2432*0b57cec5SDimitry Andric if (__rhs.__state_) 2433*0b57cec5SDimitry Andric __rhs.__state_->__add_shared(); 2434*0b57cec5SDimitry Andric if (__state_) 2435*0b57cec5SDimitry Andric __state_->__release_shared(); 2436*0b57cec5SDimitry Andric __state_ = __rhs.__state_; 2437*0b57cec5SDimitry Andric return *this; 2438*0b57cec5SDimitry Andric} 2439*0b57cec5SDimitry Andric 2440*0b57cec5SDimitry Andrictemplate <class _Rp> 2441*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&> 2442*0b57cec5SDimitry Andric{ 2443*0b57cec5SDimitry Andric __assoc_state<_Rp&>* __state_; 2444*0b57cec5SDimitry Andric 2445*0b57cec5SDimitry Andricpublic: 2446*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2447*0b57cec5SDimitry Andric shared_future() _NOEXCEPT : __state_(nullptr) {} 2448*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2449*0b57cec5SDimitry Andric shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) 2450*0b57cec5SDimitry Andric {if (__state_) __state_->__add_shared();} 2451*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2452*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2453*0b57cec5SDimitry Andric shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) 2454*0b57cec5SDimitry Andric {__f.__state_ = nullptr;} 2455*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2456*0b57cec5SDimitry Andric shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 2457*0b57cec5SDimitry Andric {__rhs.__state_ = nullptr;} 2458*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2459*0b57cec5SDimitry Andric ~shared_future(); 2460*0b57cec5SDimitry Andric shared_future& operator=(const shared_future& __rhs); 2461*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2462*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2463*0b57cec5SDimitry Andric shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 2464*0b57cec5SDimitry Andric { 2465*0b57cec5SDimitry Andric shared_future(std::move(__rhs)).swap(*this); 2466*0b57cec5SDimitry Andric return *this; 2467*0b57cec5SDimitry Andric } 2468*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2469*0b57cec5SDimitry Andric 2470*0b57cec5SDimitry Andric // retrieving the value 2471*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2472*0b57cec5SDimitry Andric _Rp& get() const {return __state_->copy();} 2473*0b57cec5SDimitry Andric 2474*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2475*0b57cec5SDimitry Andric void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2476*0b57cec5SDimitry Andric 2477*0b57cec5SDimitry Andric // functions to check state 2478*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2479*0b57cec5SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 2480*0b57cec5SDimitry Andric 2481*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2482*0b57cec5SDimitry Andric void wait() const {__state_->wait();} 2483*0b57cec5SDimitry Andric template <class _Rep, class _Period> 2484*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2485*0b57cec5SDimitry Andric future_status 2486*0b57cec5SDimitry Andric wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 2487*0b57cec5SDimitry Andric {return __state_->wait_for(__rel_time);} 2488*0b57cec5SDimitry Andric template <class _Clock, class _Duration> 2489*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2490*0b57cec5SDimitry Andric future_status 2491*0b57cec5SDimitry Andric wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 2492*0b57cec5SDimitry Andric {return __state_->wait_until(__abs_time);} 2493*0b57cec5SDimitry Andric}; 2494*0b57cec5SDimitry Andric 2495*0b57cec5SDimitry Andrictemplate <class _Rp> 2496*0b57cec5SDimitry Andricshared_future<_Rp&>::~shared_future() 2497*0b57cec5SDimitry Andric{ 2498*0b57cec5SDimitry Andric if (__state_) 2499*0b57cec5SDimitry Andric __state_->__release_shared(); 2500*0b57cec5SDimitry Andric} 2501*0b57cec5SDimitry Andric 2502*0b57cec5SDimitry Andrictemplate <class _Rp> 2503*0b57cec5SDimitry Andricshared_future<_Rp&>& 2504*0b57cec5SDimitry Andricshared_future<_Rp&>::operator=(const shared_future& __rhs) 2505*0b57cec5SDimitry Andric{ 2506*0b57cec5SDimitry Andric if (__rhs.__state_) 2507*0b57cec5SDimitry Andric __rhs.__state_->__add_shared(); 2508*0b57cec5SDimitry Andric if (__state_) 2509*0b57cec5SDimitry Andric __state_->__release_shared(); 2510*0b57cec5SDimitry Andric __state_ = __rhs.__state_; 2511*0b57cec5SDimitry Andric return *this; 2512*0b57cec5SDimitry Andric} 2513*0b57cec5SDimitry Andric 2514*0b57cec5SDimitry Andrictemplate <> 2515*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void> 2516*0b57cec5SDimitry Andric{ 2517*0b57cec5SDimitry Andric __assoc_sub_state* __state_; 2518*0b57cec5SDimitry Andric 2519*0b57cec5SDimitry Andricpublic: 2520*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2521*0b57cec5SDimitry Andric shared_future() _NOEXCEPT : __state_(nullptr) {} 2522*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2523*0b57cec5SDimitry Andric shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) 2524*0b57cec5SDimitry Andric {if (__state_) __state_->__add_shared();} 2525*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2526*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2527*0b57cec5SDimitry Andric shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) 2528*0b57cec5SDimitry Andric {__f.__state_ = nullptr;} 2529*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2530*0b57cec5SDimitry Andric shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 2531*0b57cec5SDimitry Andric {__rhs.__state_ = nullptr;} 2532*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2533*0b57cec5SDimitry Andric ~shared_future(); 2534*0b57cec5SDimitry Andric shared_future& operator=(const shared_future& __rhs); 2535*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2536*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2537*0b57cec5SDimitry Andric shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 2538*0b57cec5SDimitry Andric { 2539*0b57cec5SDimitry Andric shared_future(std::move(__rhs)).swap(*this); 2540*0b57cec5SDimitry Andric return *this; 2541*0b57cec5SDimitry Andric } 2542*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2543*0b57cec5SDimitry Andric 2544*0b57cec5SDimitry Andric // retrieving the value 2545*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2546*0b57cec5SDimitry Andric void get() const {__state_->copy();} 2547*0b57cec5SDimitry Andric 2548*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2549*0b57cec5SDimitry Andric void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2550*0b57cec5SDimitry Andric 2551*0b57cec5SDimitry Andric // functions to check state 2552*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2553*0b57cec5SDimitry Andric bool valid() const _NOEXCEPT {return __state_ != nullptr;} 2554*0b57cec5SDimitry Andric 2555*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2556*0b57cec5SDimitry Andric void wait() const {__state_->wait();} 2557*0b57cec5SDimitry Andric template <class _Rep, class _Period> 2558*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2559*0b57cec5SDimitry Andric future_status 2560*0b57cec5SDimitry Andric wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 2561*0b57cec5SDimitry Andric {return __state_->wait_for(__rel_time);} 2562*0b57cec5SDimitry Andric template <class _Clock, class _Duration> 2563*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2564*0b57cec5SDimitry Andric future_status 2565*0b57cec5SDimitry Andric wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 2566*0b57cec5SDimitry Andric {return __state_->wait_until(__abs_time);} 2567*0b57cec5SDimitry Andric}; 2568*0b57cec5SDimitry Andric 2569*0b57cec5SDimitry Andrictemplate <class _Rp> 2570*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2571*0b57cec5SDimitry Andricvoid 2572*0b57cec5SDimitry Andricswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT 2573*0b57cec5SDimitry Andric{ 2574*0b57cec5SDimitry Andric __x.swap(__y); 2575*0b57cec5SDimitry Andric} 2576*0b57cec5SDimitry Andric 2577*0b57cec5SDimitry Andrictemplate <class _Rp> 2578*0b57cec5SDimitry Andricinline 2579*0b57cec5SDimitry Andricshared_future<_Rp> 2580*0b57cec5SDimitry Andricfuture<_Rp>::share() _NOEXCEPT 2581*0b57cec5SDimitry Andric{ 2582*0b57cec5SDimitry Andric return shared_future<_Rp>(_VSTD::move(*this)); 2583*0b57cec5SDimitry Andric} 2584*0b57cec5SDimitry Andric 2585*0b57cec5SDimitry Andrictemplate <class _Rp> 2586*0b57cec5SDimitry Andricinline 2587*0b57cec5SDimitry Andricshared_future<_Rp&> 2588*0b57cec5SDimitry Andricfuture<_Rp&>::share() _NOEXCEPT 2589*0b57cec5SDimitry Andric{ 2590*0b57cec5SDimitry Andric return shared_future<_Rp&>(_VSTD::move(*this)); 2591*0b57cec5SDimitry Andric} 2592*0b57cec5SDimitry Andric 2593*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2594*0b57cec5SDimitry Andric 2595*0b57cec5SDimitry Andricinline 2596*0b57cec5SDimitry Andricshared_future<void> 2597*0b57cec5SDimitry Andricfuture<void>::share() _NOEXCEPT 2598*0b57cec5SDimitry Andric{ 2599*0b57cec5SDimitry Andric return shared_future<void>(_VSTD::move(*this)); 2600*0b57cec5SDimitry Andric} 2601*0b57cec5SDimitry Andric 2602*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2603*0b57cec5SDimitry Andric 2604*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 2605*0b57cec5SDimitry Andric 2606*0b57cec5SDimitry Andric#endif // !_LIBCPP_HAS_NO_THREADS 2607*0b57cec5SDimitry Andric 2608*0b57cec5SDimitry Andric#endif // _LIBCPP_FUTURE 2609