1[/ 2 (C) Copyright 2008-11 Anthony Williams. 3 (C) Copyright 2012-2015 Vicente J. Botet Escriba. 4 Distributed under the Boost Software License, Version 1.0. 5 (See accompanying file LICENSE_1_0.txt or copy at 6 http://www.boost.org/LICENSE_1_0.txt). 7] 8 9 10[///////////////////////////////////] 11[section:reference Futures Reference] 12 13 //#include <boost/thread/future.hpp> 14 15 namespace boost 16 { 17 namespace future_state // EXTENSION 18 { 19 enum state {uninitialized, waiting, ready, moved}; 20 } 21 22 enum class future_errc 23 { 24 broken_promise, 25 future_already_retrieved, 26 promise_already_satisfied, 27 no_state 28 }; 29 30 enum class launch 31 { 32 none = unspecified, 33 async = unspecified, 34 deferred = unspecified, 35 executor = unspecified, 36 inherit = unspecified, 37 any = async | deferred 38 }; 39 40 enum class future_status { 41 ready, timeout, deferred 42 }; 43 44 namespace system 45 { 46 template <> 47 struct is_error_code_enum<future_errc> : public true_type {}; 48 49 error_code make_error_code(future_errc e); 50 51 error_condition make_error_condition(future_errc e); 52 } 53 54 const system::error_category& future_category(); 55 56 class future_error; 57 58 class exceptional_ptr; 59 60 template <typename R> 61 class promise; 62 63 template <typename R> 64 void swap(promise<R>& x, promise<R>& y) noexcept; 65 66 namespace container { 67 template <class R, class Alloc> 68 struct uses_allocator<promise<R>, Alloc>:: true_type; 69 } 70 71 template <typename R> 72 class future; 73 74 template <typename R> 75 class shared_future; 76 77 template <typename S> 78 class packaged_task; 79 template <class S> void swap(packaged_task<S>&, packaged_task<S>&) noexcept; 80 81 template <class S, class Alloc> 82 struct uses_allocator<packaged_task <S>, Alloc>; 83 84 template <class F> 85 future<typename result_of<typename decay<F>::type()>::type> 86 async(F f); 87 template <class F> 88 future<typename result_of<typename decay<F>::type()>::type> 89 async(launch policy, F f); 90 91 template <class F, class... Args> 92 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 93 async(F&& f, Args&&... args); 94 template <class F, class... Args> 95 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 96 async(launch policy, F&& f, Args&&... args); 97 template <class Executor, class F, class... Args> 98 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 99 async(Executor &ex, F&& f, Args&&... args); 100 101 template<typename Iterator> 102 void wait_for_all(Iterator begin,Iterator end); // EXTENSION 103 template<typename F1,typename... FS> 104 void wait_for_all(F1& f1,Fs&... fs); // EXTENSION 105 106 template<typename Iterator> 107 Iterator wait_for_any(Iterator begin,Iterator end); // EXTENSION 108 template<typename F1,typename... Fs> 109 unsigned wait_for_any(F1& f1,Fs&... fs); // EXTENSION 110 111 template <class InputIterator> 112 future<std::vector<typename InputIterator::value_type::value_type>> 113 when_all(InputIterator first, InputIterator last); 114 template <typename... T> 115 future<std::tuple<decay_t<T>...> when_all(T&&... futures); 116 template <class InputIterator> 117 future<std::vector<typename InputIterator::value_type::value_type>> 118 when_any(InputIterator first, InputIterator last); // EXTENSION 119 template <typename... T> 120 future<std::tuple<decay_t<T>...> when_any(T&&... futures); 121 122 template <typename T> 123 future<typename decay<T>::type> make_future(T&& value); // DEPRECATED 124 future<void> make_future(); // DEPRECATED 125 126 template <typename T> 127 future<typename decay<T>::type> make_ready_future(T&& value); // EXTENSION 128 future<void> make_ready_future(); // EXTENSION 129 130 exceptional_ptr make_exceptional_future(exception_ptr ex); // EXTENSION 131 template <typename E> 132 exceptional_ptr make_exceptional_future(E ex); // EXTENSION 133 exceptional_ptr make_exceptional_future(); // EXTENSION 134 135 136 template <typename T> 137 shared_future<typename decay<T>::type> make_shared_future(T&& value); // DEPRECATED 138 shared_future<void> make_shared_future(); // DEPRECATED 139 140[////////////////////////////////////////] 141[section:future_state Enumeration `state`] 142 143 namespace future_state 144 { 145 enum state {uninitialized, waiting, ready, moved}; 146 } 147 148 149[endsect] 150[/////////////////////////////////////////////] 151[section:future_errc Enumeration `future_errc`] 152 153 enum class future_errc 154 { 155 broken_promise = implementation defined, 156 future_already_retrieved = implementation defined, 157 promise_already_satisfied = implementation defined, 158 no_state = implementation defined 159 } 160 161 162 The enum values of future_errc are distinct and not zero. 163 164[endsect] 165[///////////////////////////////////] 166[section:launch Enumeration `launch`] 167 168 enum class launch 169 { 170 none = unspecified, 171 async = unspecified, 172 deferred = unspecified, 173 executor = unspecified, 174 inherit = unspecified, 175 any = async | deferred 176 }; 177 178The enum type launch is a bitmask type with launch::async and launch::deferred denoting individual bits. 179 180A future created with `promise<>` or with a `packaged_task<>` or with `make_ready_future`/`make_exceptional_future` (has no associated launch policy), has an implicit a launch policy of `launch::none`. 181 182A future created by `async(launch::async, ...)` or `::then(launch::async, ...)` has associated a launch policy `launch::async`. 183A future created by `async(launch::deferred, ...)` or `::then(launch::deferred, ...)` has associated a launch policy `launch::deferred`. 184A future created by `async(Executor, ...)` or `::then(Executor, ...)` or `::then(launch::executor, ...)` has associated a launch policy `launch::executor`. 185A future created by `async(...)` or `::then(...)` has associated a launch policy `launch::none`. 186 187A future created by `::then(launch::inherit, ...)` has associated a launch policy parent future. 188 189The `executor` and the `inherit` launch policies have a sense only can be user only on `then()`. 190 191[endsect] 192[///////////////////////////////////////////////////////////////////////////] 193[section:is_error_code_enum Specialization `is_error_code_enum<future_errc>`] 194 195 namespace system 196 { 197 template <> 198 struct is_error_code_enum<future_errc> : public true_type {}; 199 200 } 201 202[endsect] 203[///////////////////////////////////////////////////////////////] 204[section:make_error_code Non-member function `make_error_code()`] 205 206 namespace system 207 { 208 error_code make_error_code(future_errc e); 209 } 210 211[variablelist 212 213[[Returns:] [`error_code(static_cast<int>(e), future_category())`.]] 214 215] 216 217[endsect] 218[/////////////////////////////////////////////////////////////////////////] 219[section:make_error_condition Non-member function `make_error_condition()`] 220 221 namespace system 222 { 223 error_condition make_error_condition(future_errc e); 224 } 225 226[variablelist 227 228[[Returns:] [`error_condition(static_cast<int>(e), future_category())`.]] 229 230] 231 232[endsect] 233[///////////////////////////////////////////////////////////////] 234[section:future_category Non-member function `future_category()`] 235 236 const system::error_category& future_category(); 237 238[variablelist 239 240[[Returns:] [A reference to an object of a type derived from class error_category.]] 241 242[[Notes:] [The object's `default_error_condition` and equivalent virtual functions behave as specified for the class `system::error_category`. 243The object's `name` virtual function returns a pointer to the string "future".]] 244 245] 246 247[endsect] 248[/////////////////////////////////////////] 249[section:future_error Class `future_error`] 250 251 class future_error 252 : public std::logic_error 253 { 254 public: 255 future_error(system::error_code ec); 256 257 const system::error_code& code() const no_except; 258 }; 259 260[///////////////////////////////] 261[section:constructor Constructor] 262 263 future_error(system::error_code ec); 264 265[variablelist 266 267[[Effects:] [Constructs a future_error.]] 268 269[[Postconditions:] [`code()==ec` ]] 270 271[[Throws:] [Nothing.]] 272 273] 274 275[endsect] 276[/////////////////////////////////////] 277[section:code Member function `code()`] 278 279 const system::error_code& code() const no_except; 280 281[variablelist 282 283[[Returns:] [The value of `ec` that was passed to the object's constructor.]] 284 285] 286 287[endsect] 288 289 290[endsect] 291[/////////////////////////////////////////////////] 292[section:future_status Enumeration `future_status`] 293 294 enum class future_status { 295 ready, timeout, deferred 296 }; 297 298[endsect] 299 300[/////////////////////////////////////////] 301[section:future_error Class `exceptional_ptr` EXPERIMENTAL] 302 303 class exceptional_ptr 304 { 305 public: 306 exceptional_ptr(); 307 explicit exceptional_ptr(exception_ptr ex); 308 template <class E> 309 explicit exceptional_ptr(E&& ex); 310 }; 311 312[///////////////////////////////] 313[section:constructor Constructor] 314 315 exceptional_ptr(); 316 explicit exceptional_ptr(exception_ptr ex); 317 template <class E> 318 explicit exceptional_ptr(E&& ex); 319 320[variablelist 321 322[[Effects:] [The exception that is passed in to the constructor or the current exception if no parameter is moved into the constructed `exceptional_ptr` if it is an rvalue. Otherwise the exception is copied into the constructed `exceptional_ptr`.]] 323 324[[Postconditions:] [ 325 `valid() == true && is_ready() = true && has_value() = false` 326]] 327 328[[Throws:] [Nothing.]] 329] 330 331[endsect] 332[endsect] 333 334 335[////////////////////////////////////////////////////] 336[section:unique_future __unique_future class template] 337 338 template <typename R> 339 class __unique_future__ 340 { 341 342 public: 343 typedef R value_type; // EXTENSION 344 __unique_future__(__unique_future__ const& rhs) = delete; 345 __unique_future__& operator=(__unique_future__ const& rhs) = delete; 346 347 __unique_future__() noexcept; 348 ~__unique_future__(); 349 350 // move support 351 __unique_future__(__unique_future__ && other) noexcept; 352 explicit __unique_future__(__unique_future__<__unique_future__<R>>&& rhs); // EXTENSION 353 __unique_future__& operator=(__unique_future__ && other) noexcept; 354 355 // factories 356 shared_future<R> share(); 357 358 template<typename F> 359 __unique_future__<typename boost::result_of<F(__unique_future__)>::type> 360 then(F&& func); // EXTENSION 361 template<typename Ex, typename F> 362 __unique_future__<typename boost::result_of<F(__unique_future__)>::type> 363 then(Ex& executor, F&& func); // EXTENSION 364 template<typename F> 365 __unique_future__<typename boost::result_of<F(__unique_future__)>::type> 366 then(launch policy, F&& func); // EXTENSION 367 368 see below unwrap(); // EXTENSION 369 __unique_future__ fallback_to(); // EXTENSION 370 371 void swap(__unique_future__& other) noexcept; 372 373 // retrieving the value 374 see below get(); 375 see below get_or(see below); // EXTENSION 376 377 exception_ptr get_exception_ptr(); // EXTENSION 378 379 // functions to check state 380 bool valid() const noexcept; 381 bool is_ready() const; // EXTENSION 382 bool has_exception() const; // EXTENSION 383 bool has_value() const; // EXTENSION 384 385 // waiting for the result to be ready 386 void wait() const; 387 template <class Rep, class Period> 388 future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const; 389 template <class Clock, class Duration> 390 future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 391 392 #if defined BOOST_THREAD_USES_DATE_TIME 393 template<typename Duration> 394 bool timed_wait(Duration const& rel_time) const; // DEPRECATED SINCE V3.0.0 395 bool timed_wait_until(boost::system_time const& abs_time) const; // DEPRECATED SINCE V3.0.0 396 #endif 397 typedef future_state::state state; // EXTENSION 398 state get_state() const; // EXTENSION 399 }; 400 401[///////////////////////////////////////////////] 402[section:default_constructor Default Constructor] 403 404 __unique_future__(); 405 406[variablelist 407 408[[Effects:] [Constructs an uninitialized __unique_future__.]] 409 410[[Postconditions:] [[unique_future_is_ready_link `this->is_ready`] returns `false`. [unique_future_get_state_link 411`this->get_state()`] returns __uninitialized__.]] 412 413[[Throws:] [Nothing.]] 414 415] 416 417[endsect] 418 419[/////////////////////////////] 420[section:destructor Destructor] 421 422 ~__unique_future__(); 423 424[variablelist 425 426[[Effects:] [Destroys `*this`.]] 427 428[[Throws:] [Nothing.]] 429 430] 431 432[endsect] 433[/////////////////////////////////////////] 434[section:move_constructor Move Constructor] 435 436 __unique_future__(__unique_future__ && other); 437 438[variablelist 439 440[[Effects:] [Constructs a new __unique_future__, and transfers ownership of the shared state associated with `other` to `*this`.]] 441 442[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the 443call. `other->get_state()` returns __uninitialized__. If `other` was associated with a shared state, that result is now 444associated with `*this`. `other` is not associated with any shared state.]] 445 446[[Throws:] [Nothing.]] 447 448[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] 449 450] 451 452[endsect] 453[///////////////////////////////////////////////////////////////////] 454[section:unwrap_move_constructor Unwrap Move Constructor - EXTENSION] 455 456 explicit __unique_future__(__unique_future__<__unique_future__<R>>&& other); // EXTENSION 457 458[warning This constructor is experimental and subject to change in future versions. 459There are not too much tests yet, so it is possible that you can find out some trivial bugs :(] 460 461[variablelist 462 463[[Requires:] [`other.valid()`.] 464 465[[Effects:] [Constructs a new __unique_future__, and transfers ownership of the shared state associated with `other` and unwrapping the inner future (see `unwrap()`).]] 466 467[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the 468call. `other->get_state()` returns __uninitialized__. The associated shared state is now 469unwrapped and the inner future shared state is associated with `*this`. `other` is not associated with any shared state, `! other.valid()`.]] 470 471[[Throws:] [Nothing.]] 472 473[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] 474 475] 476 477[endsect] 478[////////////////////////////////////////////////] 479[section:move_assignment Move Assignment Operator] 480 481 __unique_future__& operator=(__unique_future__ && other); 482 483[variablelist 484 485[[Effects:] [Transfers ownership of the shared state associated with `other` to `*this`.]] 486 487[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the 488call. `other->get_state()` returns __uninitialized__. If `other` was associated with a shared state, that result is now 489associated with `*this`. `other` is not associated with any shared state. If `*this` was associated with an asynchronous 490result prior to the call, that result no longer has an associated __unique_future__ instance.]] 491 492[[Throws:] [Nothing.]] 493 494[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] 495 496] 497 498[endsect] 499[/////////////////////////////////////] 500[section:swap Member function `swap()`] 501 502 void swap(__unique_future__ & other) no_except; 503 504[variablelist 505 506[[Effects:] [Swaps ownership of the shared states associated with `other` and `*this`.]] 507 508[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the 509call. `other->get_state()` returns the value of `this->get_state()` prior to the call. If `other` was associated with a 510shared state, that result is now associated with `*this`, otherwise `*this` has no associated result. If `*this` was 511associated with a shared state, that result is now associated with `other`, otherwise `other` has no associated result.]] 512 513[[Throws:] [Nothing.]] 514 515] 516 517[endsect] 518[///////////////////////////////////] 519[section:get Member function `get()`] 520 521 R get(); 522 R& __unique_future__<R&>::get(); 523 void __unique_future__<void>::get(); 524 525[variablelist 526 527[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready as-if by a call to 528__unique_future_wait__, and retrieves the result (whether that is a value or an exception).]] 529 530[[Returns:] [ 531 532- `__unique_future__<R&>::get()` return the stored reference. 533 534- `__unique_future__<void>::get()`, there is no return value. 535 536- `__unique_future__<R>::get()` returns an rvalue-reference to the value stored in the shared state. 537 538]] 539 540[[Postconditions:] [[unique_future_is_ready_link `this->is_ready()`] returns `true`. [unique_future_get_state_link 541`this->get_state()`] returns __ready__.]] 542 543[[Throws:] [ 544 545- __future_uninitialized__ if `*this` is not associated with a shared state. 546 547- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 548 549- Any exception stored in the shared state in place of a value. 550]] 551 552[[Notes:] [`get()` is an ['interruption point].]] 553 554] 555 556[endsect] 557[/////////////////////////////////////////////////////] 558[section:get_or Member function `get_or()` - EXTENSION] 559 560 R get_or(R&& v); // EXTENSION 561 R get_or(R const& v); // EXTENSION 562 R& __unique_future__<R&>::get_or(R& v); // EXTENSION 563 void __unique_future__<void>::get_or(); // EXTENSION 564 565[warning These functions are experimental and subject to change in future versions. 566There are not too much tests yet, so it is possible that you can find out some trivial bugs :(] 567 568[variablelist 569 570[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready as-if by a call to 571__unique_future_wait__, and depending on whether the shared state `has_value()` the retrieves the result.]] 572 573[[Returns:] [ 574 575- `__unique_future__<R&>::get_or(v)` return the stored reference if has_value() and the passes parameter otherwise. 576 577- `__unique_future__<void>::get_or()`, there is no return value, but the function doesn't throws even if the shared state contained an exception. 578 579- `__unique_future__<R>::get_or(v)` returns an rvalue-reference to the value stored in the shared state if `has_value()` and an rvalue-reference build with the parameter `v`. 580 581]] 582 583[[Postconditions:] [[unique_future_is_ready_link `this->is_ready()`] returns `true`. [unique_future_get_state_link 584`this->get_state()`] returns __ready__.]] 585 586[[Throws:] [ 587 588- __future_uninitialized__ if `*this` is not associated with a shared state. 589 590]] 591 592[[Notes:] [`get_or()` is an ['interruption point].]] 593 594] 595 596[endsect] 597[/////////////////////////////////////] 598[section:wait Member function `wait()`] 599 600 void wait() const; 601 602[variablelist 603 604[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready. If the result is not ready on 605entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]] 606 607[[Throws:] [ 608 609- __future_uninitialized__ if `*this` is not associated with a shared state. 610 611- __thread_interrupted__ if the result 612associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 613 614- Any exception thrown by the ['wait callback] if such a callback is called.]] 615 616[[Postconditions:] [[unique_future_is_ready_link `this->is_ready()`] returns `true`. [unique_future_get_state_link 617`this->get_state()`] returns __ready__.]] 618 619[[Notes:] [`wait()` is an ['interruption point].]] 620 621] 622 623[endsect] 624[//////////////////////////////////////////////////////////////////////////////////] 625[section:timed_wait_duration Member function `timed_wait()` DEPRECATED SINCE V3.0.0] 626 627 template<typename Duration> 628 bool timed_wait(Duration const& wait_duration); 629 630[warning 631DEPRECATED since 3.00. 632 633Use instead __wait_for. 634] 635 636[variablelist 637 638[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready, or the time specified by 639`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is 640invoked prior to waiting.]] 641 642[[Returns:] [`true` if `*this` is associated with a shared state, and that result is ready before the specified time has 643elapsed, `false` otherwise.]] 644 645[[Throws:] [ 646 647- __future_uninitialized__ if `*this` is not associated with a shared state. 648 649- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 650 651- Any exception thrown by the ['wait callback] if such a callback is called.]] 652 653[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and 654[unique_future_get_state_link `this->get_state()`] returns __ready__.]] 655 656[[Notes:] [`timed_wait()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]] 657 658] 659 660[endsect] 661[//////////////////////////////////////////////////////////////////////////////////] 662[section:timed_wait_absolute Member function `timed_wait()` DEPRECATED SINCE V3.0.0] 663 664 bool timed_wait(boost::system_time const& wait_timeout); 665 666[warning 667DEPRECATED since 3.00. 668 669Use instead __wait_until. 670] 671 672[variablelist 673 674[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready, or the time point specified by 675`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked 676prior to waiting.]] 677 678[[Returns:] [`true` if `*this` is associated with a shared state, and that result is ready before the specified time has 679passed, `false` otherwise.]] 680 681[[Throws:] [ 682 683- __future_uninitialized__ if `*this` is not associated with a shared state. 684 685- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 686 687- Any exception thrown by the ['wait callback] if such a callback is called.]] 688 689[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and 690[unique_future_get_state_link `this->get_state()`] returns __ready__.]] 691 692[[Notes:] [`timed_wait()` is an ['interruption point].]] 693 694] 695 696[endsect] 697[/////////////////////////////////////////////] 698[section:wait_for Member function `wait_for()`] 699 700 template <class Rep, class Period> 701 future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const; 702 703[variablelist 704 705[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready, or the time specified by 706`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is 707invoked prior to waiting.]] 708 709[[Returns:] [ 710 711- `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet) 712 713- `future_status::ready` if the shared state is ready. 714 715- `future_status::timeout` if the function is returning because the relative timeout specified by `rel_time` has expired. 716 717]] 718 719[[Throws:] [ 720 721- __future_uninitialized__ if `*this` is not associated with a shared state. 722 723- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 724 725- Any exception thrown by the ['wait callback] if such a callback is called.]] 726 727[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and 728[unique_future_get_state_link `this->get_state()`] returns __ready__.]] 729 730[[Notes:] [`wait_for()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]] 731 732] 733 734[endsect] 735[/////////////////////////////////////////////////] 736[section:wait_until Member function `wait_until()`] 737 738 template <class Clock, class Duration> 739 future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 740 741[variablelist 742 743[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready, or the time point specified by 744`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked 745prior to waiting.]] 746 747[[Returns:] [ 748 749- `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet) 750 751- `future_status::ready` if the shared state is ready. 752 753- `future_status::timeout` if the function is returning because the absolute timeout specified by `absl_time` has reached. 754 755]] 756 757[[Throws:] [ 758 759- __future_uninitialized__ if `*this` is not associated with a shared state. 760 761- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 762 763- Any exception thrown by the ['wait callback] if such a callback is called.]] 764 765[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and 766[unique_future_get_state_link `this->get_state()`] returns __ready__.]] 767 768[[Notes:] [`wait_until()` is an ['interruption point].]] 769 770] 771 772[endsect] 773[///////////////////////////////////////] 774[section:valid Member function `valid()`] 775 776 bool valid() const noexcept; 777 778[variablelist 779 780[[Returns:] [`true` if `*this` is associated with a shared state, `false` 781otherwise.]] 782 783[[Remarks:] [The result of this function is not stable and that the future could become invalid even if the function returned true or vice-versa.]] 784 785[[Throws:] [Nothing.]] 786 787] 788 789[endsect] 790[///////////////////////////////////////////////////////] 791[section:is_ready Member function `is_ready()` EXTENSION] 792 793 bool is_ready() const; 794 795[variablelist 796 797[[Returns:] [`true` if `*this` is associated with a shared state and that result is ready for retrieval, `false` 798otherwise.]] 799 800[[Remarks:] [The result of this function is not stable and that the future could become not ready even if the function returned true or vice-versa.]] 801 802[[Throws:] [Nothing.]] 803 804] 805 806[endsect] 807[/////////////////////////////////////////////////////////] 808[section:has_value Member function `has_value()` EXTENSION] 809 810 bool has_value() const; 811 812[variablelist 813 814[[Returns:] [`true` if `*this` is associated with a shared state, that result is ready for retrieval, and the result is a 815stored value, `false` otherwise.]] 816 817[[Remarks:] [The result of this function is not stable and the future could lost its value even if the function returned true or vice-versa.]] 818 819[[Throws:] [Nothing.]] 820 821] 822 823[endsect] 824[/////////////////////////////////////////////////////////////////] 825[section:has_exception Member function `has_exception()` EXTENSION] 826 827 bool has_exception() const; 828 829[variablelist 830 831[[Returns:] [`true` if `*this` is associated with a shared state, that result is ready for retrieval, and the result is a 832stored exception, `false` otherwise.]] 833 834[[Remarks:] [The result of this function is not stable and the future could lost its exception even if the function returned true or vice-versa.]] 835 836[[Throws:] [Nothing.]] 837 838] 839 840[endsect] 841[/////////////////////////////////////////////////////////////////] 842[section:get_exception_ptr Member function `get_exception_ptr()` EXTENSION] 843 844 exception_ptr get_exception_ptr(); 845 846[variablelist 847 848[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready. If the result is not ready on 849entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]] 850 851[[Returns:] [an exception_ptr, storing or not an exception.]] 852 853[[Remarks:] [The result of this function is not stable and the future could lost its exception even if the function returned a valid `exception_ptr` or vice-versa.]] 854 855[[Throws:] [Whatever `mutex::lock()/mutex::unlock()` can throw.]] 856 857] 858 859[endsect] 860[/////////////////////////////////////////////////////////] 861[section:get_state Member function `get_state()` EXTENSION] 862 863 future_state::state get_state(); 864 865[variablelist 866 867[[Effects:] [Determine the state of the shared state associated with `*this`, if any.]] 868 869[[Returns:] [__uninitialized__ if `*this` is not associated with a shared state. __ready__ if the shared state 870associated with `*this` is ready for retrieval, __waiting__ otherwise.]] 871 872[[Remarks:] [The result of this function is not stable.]] 873 874[[Throws:] [Nothing.]] 875 876] 877 878 879[endsect] 880[///////////////////////////////////////] 881[section:share Member function `share()`] 882 883 shared_future<R> share(); 884 885[variablelist 886 887[[Returns:] [`shared_future<R>(boost::move(*this))`.]] 888 889[[Postconditions:] [`this->valid() == false`.]] 890 891] 892 893 894[endsect] 895[/////////////////////////////////////////////////] 896[section:then Member function `then()` - EXTENSION] 897 898 template<typename F> 899 __unique_future__<typename boost::result_of<F(__unique_future__)>::type> 900 then(F&& func); // EXTENSION 901 template<typename Ex, typename F> 902 __unique_future__<typename boost::result_of<F(__unique_future__)>::type> 903 then(Ex& executor, F&& func); // EXTENSION 904 template<typename F> 905 __unique_future__<typename boost::result_of<F(__unique_future__)>::type> 906 then(launch policy, F&& func); // EXTENSION 907 908[warning These functions are experimental and subject to change in future versions. 909There are not too much tests yet, so it is possible that you can find out some trivial bugs :(] 910 911[note These functions are based on the [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3634.pdf [*N3634 - Improvements to std::future<T> and related APIs]] C++1y proposal by N. Gustafsson, A. Laksberg, H. Sutter, S. Mithani.] 912 913[variablelist 914 915[[Notes:] [The three functions differ only by input parameters. The first only takes a callable object which accepts a 916future object as a parameter. The second function takes an executor as the first parameter and a callable object as 917the second parameter. The third function takes a launch policy as the first parameter and a callable object as the 918second parameter.]] 919 920[[Requires:] [`INVOKE(DECAY_COPY (std::forward<F>(func)), std::move(*this))` shall be a valid expression.]] 921 922[[Effects:] [ 923 924All the functions create a shared state that is associated with the returned future object. Additionally, 925 926- When the object's shared state is ready, the continuation 927`INVOKE(DECAY_COPY(std::forward<F>(func)), std::move(*this))` is called depending on the overload (see below) with the call to DECAY_COPY() being evaluated in the thread that called then. 928 929- Any value returned from the continuation is stored as the result in the shared state of the resulting `future`. 930Any exception propagated from the execution of the continuation is stored as the exceptional result in the shared state of the resulting `future`. 931 932 933The continuation launches according to the specified policy or executor or noting. 934 935- When the launch policy is `launch::none` the continuation is called on an unspecified thread of execution. 936 937- When the launch policy is `launch::async` the continuation is called on a new thread of execution. 938 939- When the launch policy is `launch::deferred` the continuation is called on demand. 940 941- When the launch policy is `launch::executor` the continuation is called on one of the thread of execution of the executor. 942 943- When the launch policy is `launch::inherit` the continuation inherits the parent's launch policy or executor. 944 945- When the executor or launch policy is not provided (first overload) is if as if launch::none was specified. 946 947- When the executor is provided (second overload) the continuation is called on one of the thread of execution of the executor. 948 949- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy 950executor, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is 951`launch::deferred`. 952 953]] 954 955[[Returns:] [An object of type `__unique_future__<typename boost::result_of<F(__unique_future__)>` that refers to the shared state created by the continuation.]] 956 957[[Notes:] [ 958 959- Note that nested futures are not implicitly unwrapped yet. This could be subject to change in future versions. 960 961- The returned futures behave as the ones returned from boost::async, the destructor of the future object returned from then will block. This could be subject to change in future versions. 962]] 963 964[[Postconditions:] [ 965 966- The `__unique_future__` object passed to the parameter of the continuation function is a copy of the original `__unique_future__`. 967 968- `valid() == false` on original future; `valid() == true` on the `future` returned from then. 969 970[/ In case of implicit unwrapping, the validity of the `future` returned from `then` cannot be established until after the completion of the functor passed into `then`. In such case, the resulting `future` becomes ready with an exception of type `future_error`, with an error code of `future_errc::broken_promise`. ] 971 972]] 973 974] 975 976[endsect] 977[///////////////////////////////////////////////////] 978[section:unwrap Member function `unwrap()` EXTENSION] 979 980 template <typename R2> 981 __unique_future__<R2> __unique_future__<__unique_future__<R2>>::unwrap(); // EXTENSION 982 template <typename R2> 983 __shared_future__<R2> __unique_future__<__shared_future__<R2>>::unwrap(); // EXTENSION 984 985[warning These functions are experimental and subject to change in future versions. 986There are not too much tests yet, so it is possible that you can find out some trivial bugs :(] 987 988[note These functions are based on the [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3634.pdf [*N3634 - Improvements to std::future<T> and related APIs]] C++1y proposal by N. Gustafsson, A. Laksberg, H. Sutter, S. Mithani.] 989 990[variablelist 991 992[[Notes:] [Removes the outermost future and returns a future with the associated state been a proxy of the outer future.]] 993 994[[Effects:] [ 995 996- Returns a future that becomes ready when the shared state of the outer and inner future is ready. The validity of the future returned from `get()` applied on the outer future cannot be established a priori. If it is not valid, this future is forced to be valid and becomes ready with an exception of type `future_error`, with an error code of `future_errc::broken_promise`. 997 998]] 999 1000[[Returns:] [An object of type future with the associated state been a proxy of outer future.]] 1001 1002[[Postconditions:] [ 1003 1004- The returned future has `valid() == true`. 1005 1006]] 1007 1008] 1009 1010 1011[endsect] 1012 1013[endsect] 1014[////////////////////////////////////////////////////] 1015[section:shared_future `shared_future` class template] 1016 1017 template <typename R> 1018 class shared_future 1019 { 1020 public: 1021 typedef future_state::state state; // EXTENSION 1022 typedef R value_type; // EXTENSION 1023 1024 shared_future() noexcept; 1025 ~shared_future(); 1026 1027 // copy support 1028 shared_future(shared_future const& other); 1029 shared_future& operator=(shared_future const& other); 1030 1031 // move support 1032 shared_future(shared_future && other) noexcept; 1033 shared_future(__unique_future__<R> && other) noexcept; 1034 shared_future& operator=(shared_future && other) noexcept; 1035 shared_future& operator=(__unique_future__<R> && other) noexcept; 1036 1037 // factories 1038 template<typename F> 1039 __unique_future__<typename boost::result_of<F(shared_future)>::type> 1040 then(F&& func) const; // EXTENSION 1041 template<typename S, typename F> 1042 __unique_future__<typename boost::result_of<F(shared_future)>::type> 1043 then(S& scheduler, F&& func) const; // EXTENSION 1044 template<typename F> 1045 __unique_future__<typename boost::result_of<F(shared_future)>::type> 1046 then(launch policy, F&& func) const; // EXTENSION 1047 1048 void swap(shared_future& other); 1049 1050 // retrieving the value 1051 see below get() const; 1052 1053 exception_ptr get_exception_ptr(); // EXTENSION 1054 1055 // functions to check state, and wait for ready 1056 bool valid() const noexcept; 1057 bool is_ready() const noexcept; // EXTENSION 1058 bool has_exception() const noexcept; // EXTENSION 1059 bool has_value() const noexcept; // EXTENSION 1060 1061 // waiting for the result to be ready 1062 void wait() const; 1063 template <class Rep, class Period> 1064 future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const; 1065 template <class Clock, class Duration> 1066 future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 1067 1068 #if defined BOOST_THREAD_USES_DATE_TIME || defined BOOST_THREAD_DONT_USE_CHRONO 1069 template<typename Duration> 1070 bool timed_wait(Duration const& rel_time) const; // DEPRECATED SINCE V3.0.0 1071 bool timed_wait_until(boost::system_time const& abs_time) const; // DEPRECATED SINCE V3.0.0 1072 #endif 1073 state get_state() const noexcept; // EXTENSION 1074 1075 }; 1076 1077[///////////////////////////////////////////////] 1078[section:default_constructor Default Constructor] 1079 1080 shared_future(); 1081 1082[variablelist 1083 1084[[Effects:] [Constructs an uninitialized shared_future.]] 1085 1086[[Postconditions:] [[shared_future_is_ready_link `this->is_ready`] returns `false`. [shared_future_get_state_link 1087`this->get_state()`] returns __uninitialized__.]] 1088 1089[[Throws:] [Nothing.]] 1090 1091] 1092 1093[endsect] 1094[///////////////////////////////////] 1095[section:get Member function `get()`] 1096 1097 const R& get() const; 1098 R& get() const; 1099 void get() const; 1100 1101[variablelist 1102 1103[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready as-if by a call to 1104__shared_future_wait__, and returns a `const` reference to the result.]] 1105 1106[[Returns:] [ 1107 1108- `shared_future<R&>::get()` return the stored reference. 1109 1110- `shared_future<void>::get()`, there is no return value. 1111 1112- `shared_future<R>::get()` returns a `const` reference to the value stored in the shared state. 1113 1114]] 1115 1116[[Throws:] [ 1117 1118- __future_uninitialized__ if `*this` is not associated with a shared state. 1119 1120- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 1121]] 1122 1123[[Notes:] [`get()` is an ['interruption point].]] 1124 1125] 1126 1127[endsect] 1128[/////////////////////////////////////] 1129[section:wait Member function `wait()`] 1130 1131 void wait() const; 1132 1133[variablelist 1134 1135[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready. If the result is not ready on 1136entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]] 1137 1138[[Throws:] [ 1139- __future_uninitialized__ if `*this` is not associated with a shared state. 1140 1141- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 1142 1143- Any exception thrown by the 1144['wait callback] if such a callback is called.]] 1145 1146[[Postconditions:] [[shared_future_is_ready_link `this->is_ready()`] returns `true`. [shared_future_get_state_link 1147`this->get_state()`] returns __ready__.]] 1148 1149[[Notes:] [`wait()` is an ['interruption point].]] 1150 1151] 1152 1153[endsect] 1154[//////////////////////////////////////////////////////////] 1155[section:timed_wait_duration Member function `timed_wait()`] 1156 1157 template<typename Duration> 1158 bool timed_wait(Duration const& wait_duration); 1159 1160[variablelist 1161 1162[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready, or the time specified by 1163`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is 1164invoked prior to waiting.]] 1165 1166[[Returns:] [`true` if `*this` is associated with a shared state, and that result is ready before the specified time has 1167elapsed, `false` otherwise.]] 1168 1169[[Throws:] [ 1170 1171- __future_uninitialized__ if `*this` is not associated with a shared state. 1172 1173- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 1174 1175- Any exception thrown by the ['wait callback] if such a callback is called.]] 1176 1177[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and 1178[shared_future_get_state_link `this->get_state()`] returns __ready__.]] 1179 1180[[Notes:] [`timed_wait()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]] 1181 1182] 1183 1184[endsect] 1185[//////////////////////////////////////////////////////////] 1186[section:timed_wait_absolute Member function `timed_wait()`] 1187 1188 bool timed_wait(boost::system_time const& wait_timeout); 1189 1190[variablelist 1191 1192[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready, or the time point specified by 1193`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked 1194prior to waiting.]] 1195 1196[[Returns:] [`true` if `*this` is associated with a shared state, and that result is ready before the specified time has 1197passed, `false` otherwise.]] 1198 1199[[Throws:] [ 1200- __future_uninitialized__ if `*this` is not associated with a shared state. 1201 1202- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 1203 1204- Any exception thrown by the ['wait callback] if such a callback is called.]] 1205 1206[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and 1207[shared_future_get_state_link `this->get_state()`] returns __ready__.]] 1208 1209[[Notes:] [`timed_wait()` is an ['interruption point].]] 1210 1211] 1212 1213[endsect] 1214[/////////////////////////////////////////////] 1215[section:wait_for Member function `wait_for()`] 1216 1217 template <class Rep, class Period> 1218 future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const; 1219 1220 1221[variablelist 1222 1223[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready, or the time specified by 1224`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is 1225invoked prior to waiting.]] 1226 1227[[Returns:] [ 1228 1229- `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet) 1230 1231- `future_status::ready` if the shared state is ready. 1232 1233- `future_status::timeout` if the function is returning because the relative timeout specified by `rel_time` has expired. 1234 1235]] 1236 1237[[Throws:] [ 1238- __future_uninitialized__ if `*this` is not associated with a shared state. 1239 1240- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 1241 1242- Any exception thrown by the ['wait callback] if such a callback is called.]] 1243 1244[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and 1245[shared_future_get_state_link `this->get_state()`] returns __ready__.]] 1246 1247[[Notes:] [`timed_wait()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]] 1248 1249] 1250 1251[endsect] 1252[/////////////////////////////////////////////////] 1253[section:wait_until Member function `wait_until()`] 1254 1255 template <class Clock, class Duration> 1256 future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 1257 1258[variablelist 1259 1260[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready, or the time point specified by 1261`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked 1262prior to waiting.]] 1263 1264[[Returns:] [ 1265 1266- `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet) 1267 1268- `future_status::ready` if the shared state is ready. 1269 1270- `future_status::timeout` if the function is returning because the absolute timeout specified by `absl_time` has reached. 1271 1272]] 1273 1274[[Throws:] [ 1275- __future_uninitialized__ if `*this` is not associated with a shared state. 1276 1277- __thread_interrupted__ if the result associated with `*this` is not ready at the point of the call, and the current thread is interrupted. 1278 1279- Any exception thrown by the ['wait callback] if such a callback is called. 1280]] 1281 1282[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and 1283[shared_future_get_state_link `this->get_state()`] returns __ready__.]] 1284 1285[[Notes:] [`timed_wait()` is an ['interruption point].]] 1286 1287] 1288 1289[endsect] 1290[///////////////////////////////////////] 1291[section:valid Member function `valid()`] 1292 1293 bool valid() const noexcept; 1294 1295[variablelist 1296 1297[[Returns:] [`true` if `*this` is associated with a shared state, `false` 1298otherwise.]] 1299 1300[[Throws:] [Nothing.]] 1301 1302] 1303 1304[endsect] 1305[///////////////////////////////////////////////////////] 1306[section:is_ready Member function `is_ready()` EXTENSION] 1307 1308 bool is_ready() const; 1309 1310[variablelist 1311 1312[[Returns:] [`true` if `*this` is associated with a shared state, and that result is ready for retrieval, `false` 1313otherwise.]] 1314 1315[[Throws:] [Whatever `mutex::lock()/mutex::unlock()` can throw.]] 1316 1317] 1318 1319[endsect] 1320[/////////////////////////////////////////////////////////] 1321[section:has_value Member function `has_value()` EXTENSION] 1322 1323 bool has_value() const; 1324 1325[variablelist 1326 1327[[Returns:] [`true` if `*this` is associated with a shared state, that result is ready for retrieval, and the result is a 1328stored value, `false` otherwise.]] 1329 1330[[Throws:] [Whatever `mutex::lock()/mutex::unlock()` can throw.]] 1331 1332] 1333 1334[endsect] 1335[/////////////////////////////////////////////////////////////////] 1336[section:has_exception Member function `has_exception()` EXTENSION] 1337 1338 bool has_exception() const; 1339 1340[variablelist 1341 1342[[Returns:] [`true` if `*this` is associated with a shared state, that result is ready for retrieval, and the result is a 1343stored exception, `false` otherwise.]] 1344 1345[[Throws:] [Whatever `mutex::lock()/mutex::unlock()` can throw.]] 1346 1347] 1348 1349[endsect] 1350[/////////////////////////////////////////////////////////////////] 1351[section:get_exception_ptr Member function `get_exception_ptr()` EXTENSION] 1352 1353 exception_ptr get_exception_ptr(); 1354 1355[variablelist 1356 1357[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready. If the result is not ready on 1358entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]] 1359 1360[[Returns:] [an exception_ptr, storing or not an exception.]] 1361 1362[[Throws:] [Whatever `mutex::lock()/mutex::unlock()` can throw.]] 1363 1364] 1365 1366[endsect] 1367[/////////////////////////////////////////////////////////] 1368[section:get_state Member function `get_state()` EXTENSION] 1369 1370 future_state::state get_state(); 1371 1372[variablelist 1373 1374[[Effects:] [Determine the state of the shared state associated with `*this`, if any.]] 1375 1376[[Returns:] [__uninitialized__ if `*this` is not associated with a shared state. __ready__ if the shared state 1377associated with `*this` is ready for retrieval, __waiting__ otherwise.]] 1378 1379[[Throws:] [Whatever `mutex::lock()/mutex::unlock()` can throw.]] 1380 1381] 1382 1383[endsect] 1384[///////////////////////////////////////////////] 1385[section:then Member function `then()` EXTENSION] 1386 1387 template<typename F> 1388 __unique_future__<typename boost::result_of<F(shared_future)>::type> 1389 then(F&& func) const; // EXTENSION 1390 template<typename Ex, typename F> 1391 __unique_future__<typename boost::result_of<F(shared_future)>::type> 1392 then(Ex& executor, F&& func) const; // EXTENSION 1393 template<typename F> 1394 __unique_future__<typename boost::result_of<F(shared_future)>::type> 1395 then(launch policy, F&& func) const; // EXTENSION 1396 1397 1398[warning These functions are experimental and subject to change in future versions. 1399There are not too much tests yet, so it is possible that you can find out some trivial bugs :(] 1400 1401[note These functions are based on the [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3634.pdf [*N3634 - Improvements to std::future<T> and related APIs]] C++1y proposal by N. Gustafsson, A. Laksberg, H. Sutter, S. Mithani.] 1402 1403[variablelist 1404 1405[[Notes:] [The three functions differ only by input parameters. The first only takes a callable object which accepts a 1406shared_future object as a parameter. The second function takes an executor as the first parameter and a callable object as 1407the second parameter. The third function takes a launch policy as the first parameter and a callable object as the 1408second parameter.]] 1409 1410[[Requires:] [`INVOKE(DECAY_COPY (std::forward<F>(func)), *this)` shall be a valid expression.]] 1411 1412[[Effects:] [ 1413 1414All the functions create a shared state that is associated with the returned future object. Additionally, 1415 1416- When the object's shared state is ready, the continuation 1417`INVOKE(DECAY_COPY(std::forward<F>(func)), *this)` is called depending on the overload (see below) with the call to DECAY_COPY() being evaluated in the thread that called then. 1418 1419- Any value returned from the continuation is stored as the result in the shared state of the resulting `future`. 1420Any exception propagated from the execution of the continuation is stored as the exceptional result in the shared state of the resulting `future`. 1421 1422 1423The continuation launches according to the specified policy or executor or noting. 1424 1425- When the launch policy is `launch::none` the continuation is called on an unspecified thread of execution. 1426 1427- When the launch policy is `launch::async` the continuation is called on a new thread of execution. 1428 1429- When the launch policy is `launch::deferred` the continuation is called on demand. 1430 1431- When the launch policy is `launch::executor` the continuation is called on one of the thread of execution of the executor. 1432 1433- When the launch policy is `launch::inherit` the continuation inherits the parent's launch policy or executor. 1434 1435- When the executor or launch policy is not provided (first overload) is if as if launch::none was specified. 1436 1437- When the executor is provided (second overload) the continuation is called on one of the thread of execution of the executor. 1438 1439- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy 1440executor, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is 1441`launch::deferred`. 1442 1443]] 1444 1445[[Returns:] [An object of type `__unique_future__<typename boost::result_of<F(shared_future)>` that refers to the shared state created by the continuation.]] 1446 1447 1448[[Notes:] [ 1449 1450- Note that nested futures are not implicitly unwrapped yet. This could be subject to change in future versions. 1451 1452- The returned futures behave as the ones returned from boost::async, the destructor of the future object returned from then will block. This could be subject to change in future versions. 1453]] 1454 1455 1456[[Postconditions:] [ 1457 1458- The future object is moved to the parameter of the continuation function . 1459 1460- `valid() == true` on original `shared_future`; `valid() == true` on the `future` returned from then. 1461 1462[/- In case of implicit unwrapping, the validity of the `future` returned from `then` cannot be established until after the completion of the functor passed into `then`. In such case, the resulting `future` becomes ready with an exception of type `future_error`, with an error code of `future_errc::broken_promise`. ] 1463 1464]] 1465 1466] 1467 1468[endsect] 1469 1470[endsect] 1471 1472[////////////////////////////////////////] 1473[section:promise `promise` class template] 1474 1475 template <typename R> 1476 class promise 1477 { 1478 public: 1479 typedef R value_type; // EXTENSION 1480 1481 promise(); 1482 template <class Allocator> 1483 promise(allocator_arg_t, Allocator a); 1484 promise & operator=(promise const& rhs) = delete; 1485 promise(promise const& rhs) = delete; 1486 ~promise(); 1487 1488 // Move support 1489 promise(promise && rhs) noexcept;; 1490 promise & operator=(promise&& rhs) noexcept;; 1491 1492 void swap(promise& other) noexcept; 1493 // Result retrieval 1494 __unique_future__<R> get_future(); 1495 1496 // Set the value 1497 void set_value(see below); 1498 void set_exception(boost::exception_ptr e); 1499 template <typename E> 1500 void set_exception(E e); // EXTENSION 1501 1502 // setting the result with deferred notification 1503 void set_value_at_thread_exit(see below); 1504 void set_exception_at_thread_exit(exception_ptr p); 1505 template <typename E> 1506 void set_exception_at_thread_exit(E p); // EXTENSION 1507 1508 template<typename F> 1509 void set_wait_callback(F f); // EXTENSION 1510 1511 void set_value_deferred(see below); // EXTENSION 1512 void set_exception_deferred(exception_ptr p); // EXTENSION 1513 template <typename E> 1514 void set_exception_deferred(E e); // EXTENSION 1515 void notify_deferred(); // EXTENSION 1516 1517 }; 1518 1519[///////////////////////////////////////////////] 1520[section:default_constructor Default Constructor] 1521 1522 promise(); 1523 1524[variablelist 1525 1526[[Effects:] [Constructs a new __promise__ with no associated result.]] 1527 1528[[Throws:] [Nothing.]] 1529 1530] 1531 1532[endsect] 1533[///////////////////////////////////////////////] 1534[section:alloc_constructor Allocator Constructor] 1535 1536 template <class Allocator> 1537 promise(allocator_arg_t, Allocator a); 1538 1539[variablelist 1540 1541[[Effects:] [Constructs a new __promise__ with no associated result using the allocator `a`.]] 1542 1543[[Throws:] [Nothing.]] 1544 1545[[Notes:] [Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.]] 1546 1547] 1548 1549[endsect] 1550[/////////////////////////////////////////] 1551[section:move_constructor Move Constructor] 1552 1553 promise(promise && other); 1554 1555[variablelist 1556 1557[[Effects:] [Constructs a new __promise__, and transfers ownership of the result associated with `other` to `*this`, leaving `other` 1558with no associated result.]] 1559 1560[[Throws:] [Nothing.]] 1561 1562[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] 1563 1564] 1565 1566[endsect] 1567[////////////////////////////////////////////////] 1568[section:move_assignment Move Assignment Operator] 1569 1570 promise& operator=(promise && other); 1571 1572[variablelist 1573 1574[[Effects:] [Transfers ownership of the result associated with `other` to `*this`, leaving `other` with no associated result. If there 1575was already a result associated with `*this`, and that result was not ['ready], sets any futures associated with that result to 1576['ready] with a __broken_promise__ exception as the result. ]] 1577 1578[[Throws:] [Nothing.]] 1579 1580[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] 1581 1582] 1583 1584[endsect] 1585[/////////////////////////////] 1586[section:destructor Destructor] 1587 1588 ~promise(); 1589 1590[variablelist 1591 1592[[Effects:] [Destroys `*this`. If there was a result associated with `*this`, and that result is not ['ready], sets any futures 1593associated with that task to ['ready] with a __broken_promise__ exception as the result.]] 1594 1595[[Throws:] [Nothing.]] 1596 1597] 1598 1599[endsect] 1600[/////////////////////////////////////////////////] 1601[section:get_future Member Function `get_future()`] 1602 1603 __unique_future__<R> get_future(); 1604 1605[variablelist 1606 1607[[Effects:] [If `*this` was not associated with a result, allocate storage for a new shared state and associate it with 1608`*this`. Returns a __unique_future__ associated with the result associated with `*this`. ]] 1609 1610[[Throws:] [__future_already_retrieved__ if the future associated with the task has already been retrieved. `std::bad_alloc` if any 1611memory necessary could not be allocated.]] 1612 1613] 1614 1615[endsect] 1616[///////////////////////////////////////////////] 1617[section:set_value Member Function `set_value()`] 1618 1619 void set_value(R&& r); 1620 void set_value(const R& r); 1621 void promise<R&>::set_value(R& r); 1622 void promise<void>::set_value(); 1623 1624[variablelist 1625 1626[[Effects:] [ 1627- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if `*this` was not associated with a result, allocate storage for a new shared state and associate it with `*this`. 1628 1629- Store the value `r` in the shared state associated with `*this`. Any threads blocked waiting for the asynchronous 1630result are woken. 1631]] 1632 1633[[Postconditions:] [All futures waiting on the shared state are ['ready] and __unique_future_has_value__ or 1634__shared_future_has_value__ for those futures shall return `true`.]] 1635 1636[[Throws:] [ 1637- __promise_already_satisfied__ if the result associated with `*this` is already ['ready]. 1638 1639- __broken_promise__ if `*this` has no shared state. 1640 1641- `std::bad_alloc` if the memory required for storage of the result cannot be allocated. 1642 1643- Any exception thrown by the copy or move-constructor of `R`.]] 1644 1645] 1646 1647[endsect] 1648[///////////////////////////////////////////////////////] 1649[section:set_exception Member Function `set_exception()`] 1650 1651 void set_exception(boost::exception_ptr e); 1652 template <typename E> 1653 void set_exception(E e); // EXTENSION 1654 1655[variablelist 1656 1657[[Effects:] [ 1658- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if `*this` was not associated with a result, allocate storage for a new shared state and associate it with 1659`*this`. 1660 1661- Store the exception `e` in the shared state associated with `*this`. Any threads blocked waiting for the asynchronous 1662result are woken.]] 1663 1664[[Postconditions:] [All futures waiting on the shared state are ['ready] and __unique_future_has_exception__ or 1665__shared_future_has_exception__ for those futures shall return `true`.]] 1666 1667[[Throws:] [ 1668- __promise_already_satisfied__ if the result associated with `*this` is already ['ready]. 1669 1670- __broken_promise__ if `*this` has no shared state. 1671 1672- `std::bad_alloc` if the memory required for storage of the result cannot be allocated. 1673]] 1674 1675] 1676 1677[endsect] 1678[/////////////////////////////////////////////////////////////////////////////] 1679[section:set_value_at_thread_exit Member Function `set_value_at_thread_exit()`] 1680 1681 void set_value_at_thread_exit(R&& r); 1682 void set_value_at_thread_exit(const R& r); 1683 void promise<R&>::set_value_at_thread_exit(R& r); 1684 void promise<void>::set_value_at_thread_exit(); 1685 1686[variablelist 1687 1688[[Effects:] [ 1689Stores the value r in the shared state without making that state ready immediately. 1690Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration 1691associated with the current thread have been destroyed.]] 1692 1693[[Postconditions:] [the result associated with `*this` is set as deferred]] 1694 1695[[Throws:] [ 1696- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred. 1697 1698- __broken_promise__ if `*this` has no shared state. 1699 1700- `std::bad_alloc` if the memory required for storage of the result cannot be allocated. 1701 1702- Any exception thrown by the copy or move-constructor of `R`. 1703]] 1704 1705] 1706 1707[endsect] 1708[/////////////////////////////////////////////////////////////////////////////////////] 1709[section:set_exception_at_thread_exit Member Function `set_exception_at_thread_exit()`] 1710 1711 void set_exception_at_thread_exit(boost::exception_ptr e); 1712 template <typename E> 1713 void set_exception_at_thread_exit(E p); // EXTENSION 1714 1715[variablelist 1716 1717[[Effects:] [ 1718Stores the exception pointer p in the shared state without making that state ready immediately. 1719Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration 1720 associated with the current thread have been destroyed.]] 1721 1722[[Postconditions:] [the result associated with `*this` is set as deferred]] 1723 1724 1725[[Throws:] [ 1726- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred. 1727 1728- __broken_promise__ if `*this` has no shared state. 1729 1730- `std::bad_alloc` if the memory required for storage of the result cannot be allocated. 1731]] 1732 1733] 1734 1735[endsect] 1736[/////////////////////////////////////////////////////////////////////////] 1737[section:set_wait_callback Member Function `set_wait_callback()` EXTENSION] 1738 1739 template<typename F> 1740 void set_wait_callback(F f); 1741 1742[variablelist 1743 1744[[Preconditions:] [The expression `f(t)` where `t` is a lvalue of type __promise__ shall be well-formed. Invoking a copy of 1745`f` shall have the same effect as invoking `f`]] 1746 1747[[Effects:] [Store a copy of `f` with the shared state associated with `*this` as a ['wait callback]. This will replace any 1748existing wait callback store alongside that result. If a thread subsequently calls one of the wait functions on a __unique_future__ 1749or __shared_future__ associated with this result, and the result is not ['ready], `f(*this)` shall be invoked.]] 1750 1751[[Throws:] [`std::bad_alloc` if memory cannot be allocated for the required storage.]] 1752 1753] 1754 1755[endsect] 1756[///////////////////////////////////////////////] 1757[section:set_value Member Function `set_value_deferred()` EXTENSION] 1758 1759 void set_value_deferred(R&& r); 1760 void set_value_deferred(const R& r); 1761 void promise<R&>:: set_value_deferred(R& r); 1762 void promise<void>:: set_value_deferred(); 1763 1764[variablelist 1765 1766[[Effects:] [ 1767- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if `*this` was not associated with a result, allocate storage for a new shared state and associate it with `*this`. 1768 1769- Stores the value `r` in the shared state without making that state ready immediately. Threads blocked waiting for the asynchronous result are not woken. They will be woken only when `notify_deferred` is called. 1770]] 1771 1772[[Postconditions:] [the result associated with `*this` is set as deferred]] 1773 1774[[Throws:] [ 1775- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred. 1776 1777- __broken_promise__ if `*this` has no shared state. 1778 1779- `std::bad_alloc` if the memory required for storage of the result cannot be allocated. 1780 1781- Any exception thrown by the copy or move-constructor of `R`.]] 1782 1783] 1784 1785[endsect] 1786[///////////////////////////////////////////////////////] 1787[section:set_exception Member Function `set_exception_deferred()` EXTENSION] 1788 1789 void set_exception_deferred(boost::exception_ptr e); 1790 template <typename E> 1791 void set_exception_deferred(E e); // EXTENSION 1792 1793[variablelist 1794 1795[[Effects:] [ 1796- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if `*this` was not associated with a result, allocate storage for a new shared state and associate it with `*this`. 1797 1798- Store the exception `e` in the shared state associated with `*this`without making that state ready immediately. Threads blocked waiting for the asynchronous result are not woken. They will be woken only when `notify_deferred` is called.]] 1799 1800[[Postconditions:] [the result associated with `*this` is set as deferred]] 1801 1802 1803[[Throws:] [ 1804- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred. 1805 1806- __broken_promise__ if `*this` has no shared state. 1807 1808- `std::bad_alloc` if the memory required for storage of the result cannot be allocated. 1809]] 1810 1811] 1812 1813[endsect] 1814 1815[///////////////////////////////////////////////] 1816[section:set_value Member Function `notify_deferred()` EXTENSION] 1817 1818[variablelist 1819 1820[[Effects:] [ 1821Any threads blocked waiting for the asynchronous result are woken. 1822]] 1823 1824[[Postconditions:] [All futures waiting on the shared state are ['ready] and __unique_future_has_value__ or 1825__shared_future_has_value__ for those futures shall return `true`.]] 1826 1827[[Postconditions:] [the result associated with `*this` is ready.]] 1828 1829] 1830[endsect] 1831 1832 1833[endsect] 1834[////////////////////////////////////////////////////] 1835[section:packaged_task `packaged_task` class template] 1836 1837 template<typename S> 1838 class packaged_task; 1839 template<typename R 1840 , class... ArgTypes 1841 > 1842 class packaged_task<R(ArgTypes)> 1843 { 1844 public: 1845 packaged_task(packaged_task const&) = delete; 1846 packaged_task& operator=(packaged_task const&) = delete; 1847 1848 // construction and destruction 1849 packaged_task() noexcept; 1850 1851 explicit packaged_task(R(*f)(ArgTypes...)); 1852 1853 template <class F> 1854 explicit packaged_task(F&& f); 1855 1856 template <class Allocator> 1857 packaged_task(allocator_arg_t, Allocator a, R(*f)(ArgTypes...)); 1858 template <class F, class Allocator> 1859 packaged_task(allocator_arg_t, Allocator a, F&& f); 1860 1861 ~packaged_task() 1862 {} 1863 1864 // move support 1865 packaged_task(packaged_task&& other) noexcept; 1866 packaged_task& operator=(packaged_task&& other) noexcept; 1867 1868 void swap(packaged_task& other) noexcept; 1869 1870 bool valid() const noexcept; 1871 // result retrieval 1872 __unique_future__<R> get_future(); 1873 1874 // execution 1875 void operator()(ArgTypes... ); 1876 void make_ready_at_thread_exit(ArgTypes...); 1877 1878 void reset(); 1879 template<typename F> 1880 void set_wait_callback(F f); // EXTENSION 1881 }; 1882 1883[/////////////////////////////////////////] 1884[section:task_constructor Task Constructor] 1885 1886 packaged_task(R(*f)(ArgTypes...)); 1887 1888 template<typename F> 1889 packaged_task(F&&f); 1890 1891[variablelist 1892 1893[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` must behave the same 1894as invoking `f`.]] 1895 1896[[Effects:] [Constructs a new __packaged_task__ with `boost::forward<F>(f)` stored as the associated task.]] 1897 1898[[Throws:] [ 1899 1900- Any exceptions thrown by the copy (or move) constructor of `f`. 1901 1902- `std::bad_alloc` if memory for the internal data structures could not be allocated. 1903]] 1904 1905[[Notes:] [The R(*f)(ArgTypes...)) overload to allow passing a function without needing to use `&`.]] 1906 1907[[Remark:] [This constructor doesn't participate in overload resolution if decay<F>::type is the same type as boost::packaged_task<R>.]] 1908 1909 1910] 1911 1912[endsect] 1913[///////////////////////////////////////////////] 1914[section:alloc_constructor Allocator Constructor] 1915 1916 template <class Allocator> 1917 packaged_task(allocator_arg_t, Allocator a, R(*f)(ArgTypes...)); 1918 template <class F, class Allocator> 1919 packaged_task(allocator_arg_t, Allocator a, F&& f); 1920 1921[variablelist 1922 1923[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same 1924as invoking `f`.]] 1925 1926[[Effects:] [Constructs a new __packaged_task with `boost::forward<F>(f)` stored as the associated task using the allocator `a`.]] 1927 1928[[Throws:] [Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data 1929structures could not be allocated.]] 1930 1931[[Notes:] [Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.]] 1932[[Notes:] [The R(*f)(ArgTypes...)) overload to allow passing a function without needing to use `&`.]] 1933 1934] 1935 1936[endsect] 1937[/////////////////////////////////////////] 1938[section:move_constructor Move Constructor] 1939 1940 packaged_task(packaged_task && other); 1941 1942[variablelist 1943 1944[[Effects:] [Constructs a new __packaged_task__, and transfers ownership of the task associated with `other` to `*this`, leaving `other` 1945with no associated task.]] 1946 1947[[Throws:] [Nothing.]] 1948 1949[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] 1950 1951] 1952 1953[endsect] 1954[////////////////////////////////////////////////] 1955[section:move_assignment Move Assignment Operator] 1956 1957 packaged_task& operator=(packaged_task && other); 1958 1959[variablelist 1960 1961[[Effects:] [Transfers ownership of the task associated with `other` to `*this`, leaving `other` with no associated task. If there 1962was already a task associated with `*this`, and that task has not been invoked, sets any futures associated with that task to 1963['ready] with a __broken_promise__ exception as the result. ]] 1964 1965[[Throws:] [Nothing.]] 1966 1967[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] 1968 1969] 1970 1971[endsect] 1972[/////////////////////////////] 1973[section:destructor Destructor] 1974 1975 ~packaged_task(); 1976 1977[variablelist 1978 1979[[Effects:] [Destroys `*this`. If there was a task associated with `*this`, and that task has not been invoked, sets any futures 1980associated with that task to ['ready] with a __broken_promise__ exception as the result.]] 1981 1982[[Throws:] [Nothing.]] 1983 1984] 1985 1986[endsect] 1987[/////////////////////////////////////////////////] 1988[section:get_future Member Function `get_future()`] 1989 1990 __unique_future__<R> get_future(); 1991 1992[variablelist 1993 1994[[Effects:] [Returns a __unique_future__ associated with the result of the task associated with `*this`. ]] 1995 1996[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of 1997__packaged_task__. __future_already_retrieved__ if the future associated with the task has already been retrieved.]] 1998 1999] 2000 2001[endsect] 2002[////////////////////////////////////////////////////] 2003[section:call_operator Member Function `operator()()`] 2004 2005 void operator()(); 2006 2007[variablelist 2008 2009[[Effects:] [Invoke the task associated with `*this` and store the result in the corresponding future. If the task returns normally, 2010the return value is stored as the shared state, otherwise the exception thrown is stored. Any threads blocked waiting for the 2011shared state associated with this task are woken.]] 2012 2013[[Postconditions:] [All futures waiting on the shared state are ['ready]]] 2014 2015[[Throws:] [ 2016 2017- __task_moved__ if ownership of the task associated with `*this` has been moved to another instance of __packaged_task__. 2018 2019- __task_already_started__ if the task has already been invoked.]] 2020 2021] 2022 2023[endsect] 2024[///////////////////////////////////////////////////////////////////////////////] 2025[section:make_ready_at_thread_exit Member Function `make_ready_at_thread_exit()`] 2026 2027 void make_ready_at_thread_exit(ArgTypes...); 2028 2029[variablelist 2030 2031[[Effects:] [Invoke the task associated with `*this` and store the result in the corresponding future. If the task returns normally, 2032the return value is stored as the shared state, otherwise the exception thrown is stored. 2033In either case, this is done without making that state ready immediately. 2034Schedules the shared state to be made ready when the current thread exits, after all objects of thread storage 2035duration associated with the current thread have been destroyed.]] 2036 2037[[Throws:] [ 2038 2039- __task_moved__ if ownership of the task associated with `*this` has been moved to another instance of __packaged_task__. 2040 2041- __task_already_started__ if the task has already been invoked. 2042]] 2043 2044] 2045 2046[endsect] 2047[///////////////////////////////////////] 2048[section:reset Member Function `reset()`] 2049 2050 void reset(); 2051 2052[variablelist 2053 2054[[Effects:] [Reset the state of the packaged_task so that it can be called again.]] 2055 2056[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of 2057__packaged_task__.]] 2058 2059] 2060 2061[endsect] 2062[/////////////////////////////////////////////////////////////////////////] 2063[section:set_wait_callback Member Function `set_wait_callback()` EXTENSION] 2064 2065 template<typename F> 2066 void set_wait_callback(F f); 2067 2068[variablelist 2069 2070[[Preconditions:] [The expression `f(t)` where `t` is a lvalue of type __packaged_task__ shall be well-formed. Invoking a copy of 2071`f` shall have the same effect as invoking `f`]] 2072 2073[[Effects:] [Store a copy of `f` with the task associated with `*this` as a ['wait callback]. This will replace any existing wait 2074callback store alongside that task. If a thread subsequently calls one of the wait functions on a __unique_future__ or 2075__shared_future__ associated with this task, and the result of the task is not ['ready], `f(*this)` shall be invoked.]] 2076 2077[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of 2078__packaged_task__.]] 2079 2080] 2081 2082[endsect] 2083 2084 2085[endsect] 2086[//////////////////////////////////////////////////////] 2087[section:decay_copy Non-member function `decay_copy()`] 2088 template <class T> 2089 typename decay<T>::type decay_copy(T&& v) 2090 { 2091 return boost::forward<T>(v); 2092 } 2093 2094[endsect] 2095[///////////////////////////////////////////] 2096[section:async Non-member function `async()`] 2097 2098 2099The function template async provides a mechanism to launch a function potentially in a new thread and 2100provides the result of the function in a future object with which it shares a shared state. 2101 2102[heading Non-Variadic variant] 2103 2104 template <class F> 2105 __unique_future__<typename result_of<typename decay<F>::type()>::type> 2106 async(F&& f); 2107 template <class F> 2108 __unique_future__<typename result_of<typename decay<F>::type()>::type> 2109 async(launch policy, F&& f); 2110 template <class Executor, class F> 2111 __unique_future__<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 2112 async(Executor &ex, F&& f, Args&&... args); 2113[variablelist 2114 2115[[Requires:] [ 2116 2117`` 2118decay_copy(boost::forward<F>(f))() 2119`` 2120 2121shall be a valid expression. 2122]] 2123 2124[[Effects] [ 2125The first function behaves the same as a call to the second function with a policy argument of 2126 `launch::async | launch::deferred` and the same arguments for `F`. 2127 2128The second and third functions create a shared state that is associated with the returned future object. 2129 2130The further behavior of the second function depends on the policy argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies): 2131 2132- if `policy & launch::async` is non-zero - calls `decay_copy(boost::forward<F>(f))()` as if in a new thread of execution represented by a thread object with the calls to `decay_copy()` being evaluated in the thread that called `async`. Any return value is stored as the result in the shared state. Any exception propagated from the execution of `decay_copy(boost::forward<F>(f))()` is stored as the exceptional result in the shared state. The thread object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state. 2133 2134- if `policy & launch::deferred` is non-zero - Stores `decay_copy(boost::forward<F>(f))` in the shared state. This copy of `f` constitute a deferred function. Invocation of the deferred function evaluates `boost::move(g)()` where `g` is the stored value of `decay_copy(boost::forward<F>(f))`. The shared state is not made ready until the function has completed. The first call to a non-timed waiting function on an asynchronous return object referring to this shared state shall invoke the deferred function in the thread that called the waiting function. Once evaluation of `boost::move(g)()` begins, the function is no longer considered deferred. (Note: If this policy is specified together with other policies, such as when using a policy value of `launch::async | launch::deferred`, implementations should defer invocation or the selection of the policy when no more concurrency can be effectively exploited.) 2135 2136- if no valid launch policy is provided the behavior is undefined. 2137 2138 2139The further behavior of the third function is as follows: 2140 2141- The Executor::submit() function is given a function<void ()> which calls `INVOKE (DECAY_COPY 2142(std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...). The implementation of the executor 2143is decided by the programmer. 2144 2145]] 2146 2147[[Returns:] [An object of type `__unique_future__<typename result_of<typename decay<F>::type()>::type>` that refers to the shared state created by this call to `async`.]] 2148 2149[[Synchronization:] [Regardless of the provided policy argument, 2150 2151- the invocation of `async` synchronizes with the invocation of `f`. (Note: This statement applies even when the corresponding future object is moved to another thread.); and 2152 2153- the completion of the function `f` is sequenced before the shared state is made ready. (Note: `f` might not be called at all, so its completion might never happen.) 2154 2155If the implementation chooses the `launch::async` policy, 2156 2157- a call to a non-timed waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined, or else time out; 2158 2159- the associated thread completion synchronizes with the return from the first function that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first. 2160]] 2161 2162[[Throws:][`system_error` if policy is `launch::async` and the implementation is unable to start a new thread. 2163]] 2164 2165[[Error conditions:] [ 2166 2167- `resource_unavailable_try_again` - if policy is `launch::async` and the system is unable to start a new thread. 2168 2169]] 2170 2171[[Remarks::] [The first signature shall not participate in overload resolution if `decay_t<F> is `boost:: 2172launch` or `boost::is_executor<F>` is `true_type`.]] 2173 2174] 2175 2176[heading Variadic variant] 2177 2178 template <class F, class... Args> 2179 __unique_future__<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 2180 async(F&& f, Args&&... args); 2181 template <class F, class... Args> 2182 __unique_future__<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 2183 async(launch policy, F&& f, Args&&... args); 2184 template <class Executor, class F, class... Args> 2185 __unique_future__<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 2186 async(Executor &ex, F&& f, Args&&... args); 2187 2188[warning the variadic prototype is provided only on C++11 compilers supporting rvalue references, variadic templates, decltype and a standard library providing <tuple> (waiting for a boost::tuple that is move aware), and BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK is defined.] 2189 2190[variablelist 2191 2192[[Requires:] [ 2193`F` and each `Ti` in `Args` shall satisfy the `MoveConstructible` requirements. 2194 2195 invoke (decay_copy (boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...) 2196 2197shall be a valid expression. 2198 2199]] 2200[[Effects:] [ 2201 2202- The first function behaves the same as a call to the second function with a policy argument of `launch::async | launch::deferred` and the same arguments for `F` and `Args`. 2203 2204- The second function creates a shared state that is associated with the returned future object. 2205The further behavior of the second function depends on the policy argument as follows (if more than one of these conditions applies, 2206the implementation may choose any of the corresponding policies): 2207 2208 - if `policy & launch::async` is non-zero - calls `invoke(decay_copy(forward<F>(f)), decay_copy (forward<Args>(args))...)` 2209 as if in a new thread of execution represented by a thread object with the calls to `decay_copy()` being evaluated in the thread that called `async`. 2210 Any return value is stored as the result in the shared state. 2211 Any exception propagated from the execution of `invoke(decay_copy(boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...)` 2212 is stored as the exceptional result in the shared state. The thread object is stored in the shared state and 2213 affects the behavior of any asynchronous return objects that reference that state. 2214 2215 - if `policy & launch::deferred` is non-zero - Stores `decay_copy(forward<F>(f))` and `decay_copy(forward<Args>(args))...` in the shared state. 2216 These copies of `f` and `args` constitute a deferred function. Invocation of the deferred function evaluates 2217 `invoke(move(g), move(xyz))` where `g` is the stored value of `decay_copy(forward<F>(f))` and `xyz` is the stored copy of `decay_copy(forward<Args>(args))...`. 2218 The shared state is not made ready until the function has completed. The first call to a non-timed waiting function on 2219 an asynchronous return object referring to this shared state shall invoke the deferred function in the thread that called the waiting function. 2220 Once evaluation of `invoke(move(g), move(xyz))` begins, the function is no longer considered deferred. 2221 2222 - if no valid launch policy is provided the behaviour is undefined. 2223 2224]] 2225 2226[[Note:] [If this policy is specified together with other policies, such as when using a policy value of `launch::async | launch::deferred`, 2227implementations should defer invocation or the selection of the policy when no more concurrency can be effectively exploited.]] 2228 2229[[Returns:] [An object of type `__unique_future__<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>` 2230that refers to the shared state created by this call to `async`.]] 2231 2232[[Synchronization:] [Regardless of the provided policy argument, 2233 2234- the invocation of async synchronizes with the invocation of `f`. (Note: This statement applies even when the corresponding future object is moved to another thread.); and 2235 2236- the completion of the function `f` is sequenced before the shared state is made ready. (Note: f might not be called at all, so its completion might never happen.) 2237 2238If the implementation chooses the `launch::async` policy, 2239 2240- a call to a waiting function on an asynchronous return object that shares the shared state created by this async call 2241shall block until the associated thread has completed, as if joined, or else time out; 2242 2243- the associated thread completion synchronizes with the return from the first function that successfully detects the ready status of the shared state or 2244with the return from the last function that releases the shared state, whichever happens first. 2245 2246]] 2247 2248[[Throws:] [`system_error` if policy is `launch::async` and the implementation is unable to start a new thread. 2249]] 2250 2251[[Error conditions:][ 2252 2253- `resource_unavailable_try_again` - if policy is `launch::async` and the system is unable to start a new thread. 2254]] 2255 2256[[Remarks:] [The first signature shall not participate in overload resolution if decay<F>::type is boost::launch. 2257]] 2258 2259] 2260 2261 2262[endsect] 2263[/////////////////////////////////////////////////////////////////////] 2264[section:wait_for_any Non-member function `wait_for_any()` - EXTENSION] 2265 2266 template<typename Iterator> 2267 Iterator wait_for_any(Iterator begin,Iterator end); // EXTENSION 2268 2269 template<typename F1,typename F2> 2270 unsigned wait_for_any(F1& f1,F2& f2); // EXTENSION 2271 2272 template<typename F1,typename F2,typename F3> 2273 unsigned wait_for_any(F1& f1,F2& f2,F3& f3); // EXTENSION 2274 2275 template<typename F1,typename F2,typename F3,typename F4> 2276 unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4); // EXTENSION 2277 2278 template<typename F1,typename F2,typename F3,typename F4,typename F5> 2279 unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5); // EXTENSION 2280 2281[variablelist 2282 2283[[Preconditions:] [The types `Fn` shall be specializations of 2284__unique_future__ or __shared_future__, and `Iterator` shall be a 2285forward iterator with a `value_type` which is a specialization of 2286__unique_future__ or __shared_future__.]] 2287 2288[[Effects:] [Waits until at least one of the specified futures is ['ready].]] 2289 2290[[Returns:] [The range-based overload returns an `Iterator` identifying the first future in the range that was detected as 2291['ready]. The remaining overloads return the zero-based index of the first future that was detected as ['ready] (first parameter => 22920, second parameter => 1, etc.).]] 2293 2294[[Throws:] [__thread_interrupted__ if the current thread is interrupted. Any exception thrown by the ['wait callback] associated 2295with any of the futures being waited for. `std::bad_alloc` if memory could not be allocated for the internal wait structures.]] 2296 2297[[Notes:] [`wait_for_any()` is an ['interruption point].]] 2298 2299] 2300 2301 2302[endsect] 2303[/////////////////////////////////////////////////////////////////////] 2304[section:wait_for_all Non-member function `wait_for_all()` - EXTENSION] 2305 2306 template<typename Iterator> 2307 void wait_for_all(Iterator begin,Iterator end); // EXTENSION 2308 2309 template<typename F1,typename F2> 2310 void wait_for_all(F1& f1,F2& f2); // EXTENSION 2311 2312 template<typename F1,typename F2,typename F3> 2313 void wait_for_all(F1& f1,F2& f2,F3& f3); // EXTENSION 2314 2315 template<typename F1,typename F2,typename F3,typename F4> 2316 void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4); // EXTENSION 2317 2318 template<typename F1,typename F2,typename F3,typename F4,typename F5> 2319 void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5); // EXTENSION 2320 2321[variablelist 2322 2323[[Preconditions:] [The types `Fn` shall be specializations of 2324__unique_future__ or __shared_future__, and `Iterator` shall be a 2325forward iterator with a `value_type` which is a specialization of 2326__unique_future__ or __shared_future__.]] 2327 2328[[Effects:] [Waits until all of the specified futures are ['ready].]] 2329 2330[[Throws:] [Any exceptions thrown by a call to `wait()` on the specified futures.]] 2331 2332[[Notes:] [`wait_for_all()` is an ['interruption point].]] 2333 2334] 2335 2336 2337[endsect] 2338 2339[/////////////////////////////////////////////////////////////////////] 2340[section:when_all Non-member function `when_all()` - EXTENSION] 2341 2342 2343 template <class InputIterator> 2344 future<std::vector<typename InputIterator::value_type::value_type>> 2345 when_all(InputIterator first, InputIterator last); 2346 2347 template <typename... FutTypes> 2348 future<std::tuple<decay_t<FutTypes>...> when_all(FutTypes&&... futures); 2349 2350[variablelist 2351 2352[[Requires:] [ 2353 2354 - For the first overload, `InputIterator`'s value type shall be convertible to `future<R>` or `shared_future<R>`. 2355All `R` types must be the same. If any of the `future<R>` or `shared_future<R>` objects are in invalid state (i.e. `valid() == false`), the behavior is undefined. 2356 - For the second overload, `FutTypes` is of type `future<R>` or `shared_future<R>`. The effect of calling `when_all` on a `future` or a `shared_future` object for which `valid() == false` is undefined. 2357 2358]] 2359 2360[[Notes:] [ 2361 2362- There are two variations of `when_all`. The first version takes a pair of `InputIterators`. The second takes any arbitrary number of `future<R0>` and `shared_future<R1>` objects, where `R0` and `R1` need not be the same type. 2363 2364- Calling the first signature of `when_all` where `InputIterator` first equals last, returns a future with an empty `vector` that is immediately ready. 2365 2366- Calling the second signature of `when_all` with no arguments returns a future<tuple<>> that is immediately ready. 2367 2368]] 2369 2370[[Effects:] [ 2371 2372- If any of the futures supplied to a call to `when_all` refer to deferred tasks that have not started execution, those tasks are executed before the call to `when_all` returns. Once all such tasks have been executed, the call to `when_all` returns immediately. 2373 2374- The call to `when_all` does not wait for non-deferred tasks, or deferred tasks that have already started executing elsewhere, to complete before returning. 2375 2376- Once all the `future`s/`shared_future`s supplied to the call to `when_all` are ready, the `future`s/`shared_future`s are moved/copied into the associated state of the future returned from the call to `when_all`, preserving the order of the futures supplied to `when_all`. 2377 2378- The collection is then stored as the result in a newly created shared state. 2379 2380- A new future object that refers to the shared state is created. The exact type of the future is further described below. 2381 2382- The `future` returned by `when_all` will not throw an exception when calling `wait()` or `get()`, but the futures held in the output collection may. 2383]] 2384 2385[[Returns:] [ 2386 2387- `future<tuple<>>` if `when_all` is called with zero arguments. 2388 2389- `future<vector<future<R>>>` if the input cardinality is unknown at compile and the iterator pair yields `future<R>`. The order of the futures in the output vector will be the same as given by the input iterator. 2390 2391- `future<vector<shared_future<R>>>` if the input cardinality is unknown at compile time and the iterator pair yields `shared_future<R>`. The order of the futures in the output vector will be the same as given by the input iterator. 2392 2393- `future<tuple<decay_t<FutTypes>...>>` if inputs are fixed in number. 2394 2395]] 2396 2397[[Postconditions:] [ 2398 2399- All input futures valid() == false. 2400 2401- All input shared future valid() == true. 2402 2403- valid() == true. 2404 2405]] 2406 2407] 2408 2409 2410[endsect] 2411[/////////////////////////////////////////////////////////////////////] 2412[section:when_any Non-member function `when_any()` - EXTENSION] 2413 2414 2415 template <class InputIterator> 2416 future<std::vector<typename InputIterator::value_type::value_type>> 2417 when_any(InputIterator first, InputIterator last); 2418 2419 template <typename... FutTypes> 2420 future<std::tuple<decay_t<FutTypes>...> 2421 when_any(FutTypes&&... futures); 2422 2423[variablelist 2424 2425[[Requires:] [ 2426 2427 2428 2429 - For the first overload, `InputIterator`'s value type shall be convertible to `future<R>` or `shared_future<R>`. All `R` types must be the same. If any of the `future<R>` or `shared_future<R>` objects are in invalid state (i.e. `valid() == false`), the behavior is undefined. 2430 - For the second overload, `FutTypes` is of type `future<R>` or `shared_future<R>`. The effect of calling `when_any` on a `future` or a `shared_future` object for which `valid() == false is undefined`. 2431 2432]] 2433 2434[[Notes:] [ 2435 2436- There are two variations of `when_any `. The first version takes a pair of `InputIterators`. The second takes any arbitrary number of `future<R0>` and `shared_future<R1>` objects, where `R0` and `R1` need not be the same type. 2437 2438- Calling the first signature of `when_any ` where `InputIterator` first equals last, returns a future with an empty `vector` that is immediately ready. 2439 2440- Calling the second signature of `when_any` with no arguments returns a future<tuple<>> that is immediately ready. 2441 2442]] 2443 2444[[Effects:] [ 2445 2446- Each of the futures supplied to `when_any` is checked in the order supplied. If a given future is ready, then no further futures are checked, and the call to `when_any` returns immediately. If a given future refers to a deferred task that has not yet started execution, then no further futures are checked, that task is executed, and the call to `when_any` then returns immediately. 2447 2448- The call to `when_any` does not wait for non-deferred tasks, or deferred tasks that have already started executing elsewhere, to complete before returning. 2449 2450- Once at least one of the futures supplied to the call to `when_any` are ready, the futures are moved into the associated state of the future returned from the call to `when_any`, preserving the order of the futures supplied to `when_any`. That future is then ready. 2451 2452- The collection is then stored as the result in a newly created shared state. 2453 2454- A new future object that refers to the shared state is created. The exact type of the future is further described below. 2455 2456- The future returned by `when_any` will not throw an exception when calling `wait()` or `get()`, but the futures held in the output collection may. 2457 2458]] 2459 2460[[Returns:] [ 2461 2462- `future<tuple<>>` if `when_any ` is called with zero arguments. 2463 2464- `future<vector<future<R>>>` if the input cardinality is unknown at compile and the iterator pair yields `future<R>`. The order of the futures in the output vector will be the same as given by the input iterator. 2465 2466- `future<vector<shared_future<R>>>` if the input cardinality is unknown at compile time and the iterator pair yields `shared_future<R>`. The order of the futures in the output vector will be the same as given by the input iterator. 2467 2468- `future<tuple<decat_t<FutTypes>...>>` if inputs are fixed in number. 2469 2470]] 2471 2472[[Postconditions:] [ 2473 2474- All input futures valid() == false. 2475 2476- All input shared_futures valid() == true. 2477 2478- valid() == true. 2479 2480 2481]] 2482 2483] 2484 2485 2486[endsect] 2487 2488 2489[/////////////////////////////////////////////////////////////////////////////] 2490[section:make_ready_future Non-member function `make_ready_future()` EXTENSION] 2491 2492 template <typename T> 2493 future<V> make_ready_future(T&& value); // EXTENSION 2494 future<void> make_ready_future(); // EXTENSION 2495 template <typename T> 2496 future<T> make_ready_future(exception_ptr ex); // DEPRECATED 2497 template <typename T, typename E> 2498 future<T> make_ready_future(E ex); // DEPRECATED 2499 2500[variablelist 2501 2502[[Remark:][ 2503where `V` is determined as follows: Let `U` be `decay_t<T>`. Then `V` is `X&` 2504if `U` equals `reference_wrapper<X>`, otherwise `V` is `U`. 2505]] 2506[[Effects:] [ 2507- value prototype: The value that is passed into the function is moved to the shared state of the returned future if it is an rvalue. 2508Otherwise the value is copied to the shared state of the returned future. 2509 2510- exception: The exception that is passed into the function is copied to the shared state of the returned future. 2511 2512.]] 2513 2514[[Returns:] [ 2515 2516- a ready future with the value set with `value` 2517 2518- a ready future with the exception set with `ex` 2519 2520- a ready future<void> with the value set (void). 2521 2522]] 2523 2524[[Postcondition:] [ 2525 2526- Returned future, valid() == true 2527 2528- Returned future, is_ready() = true 2529 2530- Returned future, has_value() = true or has_exception() depending on the prototype. 2531 2532]] 2533 2534] 2535 2536[endsect] 2537[/////////////////////////////////////////////////////////////////////////////] 2538[section:make_exceptional_future Non-member function `make_exceptional_future()` EXTENSION] 2539 2540 exceptional_ptr make_exceptional_future(exception_ptr ex); // EXTENSION 2541 template <typename E> 2542 exceptional_ptr make_exceptional_future(E ex); // EXTENSION 2543 exceptional_ptr make_exceptional_future(); // EXTENSION 2544 2545[variablelist 2546 2547[[Effects:] [ 2548The exception that is passed in to the function or the current exception if no parameter is given is moved into the returned `exceptional_ptr` if it is an rvalue. Otherwise the exception is copied into the returned `exceptional_ptr`. 2549]] 2550 2551[[Returns:] [ 2552An exceptional_ptr instance implicitly convertible to a future<T> 2553]] 2554 2555] 2556 2557[endsect] 2558 2559[//////////////////////////////////////////////////////////////////] 2560[section:make_future Non-member function `make_future()` DEPRECATED] 2561 2562 template <typename T> 2563 future<typename decay<T>::type> make_future(T&& value); // DEPRECATED 2564 future<void> make_future(); // DEPRECATED 2565 2566 2567[variablelist 2568 2569[[Effects:] [ 2570The value that is passed into the function is moved to the shared state of the returned function if it is an rvalue. 2571Otherwise the value is copied to the shared state of the returned function. 2572.]] 2573 2574[[Returns:] [ 2575 2576- future<T>, if function is given a value of type T 2577 2578- future<void>, if the function is not given any inputs. 2579 2580]] 2581 2582[[Postcondition:] [ 2583 2584- Returned future<T>, valid() == true 2585 2586- Returned future<T>, is_ready() = true 2587 2588]] 2589 2590[[See:] [`make_ready_future()`]] 2591 2592] 2593 2594[endsect] 2595[////////////////////////////////////////////////////////////////////////////////] 2596[section:make_shared_future Non-member function `make_shared_future()` DEPRECATED] 2597 2598 template <typename T> 2599 shared_future<typename decay<T>::type> make_shared_future(T&& value); // DEPRECATED 2600 shared_future<void> make_shared_future(); // DEPRECATED 2601 2602[variablelist 2603 2604[[Effects:] [ 2605The value that is passed in to the function is moved to the shared state of the returned function if it is an rvalue. 2606Otherwise the value is copied to the shared state of the returned function. 2607.]] 2608 2609[[Returns:] [ 2610 2611- shared_future<T>, if function is given a value of type T 2612 2613- shared_future<void>, if the function is not given any inputs. 2614 2615]] 2616 2617[[Postcondition:] [ 2618 2619- Returned shared_future<T>, valid() == true 2620 2621- Returned shared_future<T>, is_ready() = true 2622 2623]] 2624 2625[[See:] [`make_ready_future()` and `future<>::share()`]] 2626 2627] 2628 2629[endsect] 2630 2631 2632[endsect] 2633