| 555 | // Used to create stand-alone futures |
| 556 | template<typename T> |
| 557 | struct shared_state: |
| 558 | detail::shared_state_base |
| 559 | { |
| 560 | #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL |
| 561 | typedef boost::optional<T> storage_type; |
| 562 | #else |
| 563 | typedef boost::csbl::unique_ptr<T> storage_type; |
| 564 | #endif |
| 565 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES |
| 566 | typedef T const& source_reference_type; |
| 567 | typedef BOOST_THREAD_RV_REF(T) rvalue_source_type; |
| 568 | typedef T move_dest_type; |
| 569 | #elif defined BOOST_THREAD_USES_MOVE |
| 570 | typedef typename conditional<boost::is_fundamental<T>::value,T,T const&>::type source_reference_type; |
| 571 | typedef BOOST_THREAD_RV_REF(T) rvalue_source_type; |
| 572 | typedef T move_dest_type; |
| 573 | #else |
| 574 | typedef T& source_reference_type; |
| 575 | typedef typename conditional<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >::value, BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type; |
| 576 | typedef typename conditional<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >::value, BOOST_THREAD_RV_REF(T),T>::type move_dest_type; |
| 577 | #endif |
| 578 | |
| 579 | typedef const T& shared_future_get_result_type; |
| 580 | |
| 581 | storage_type result; |
| 582 | |
| 583 | shared_state(): |
| 584 | result() |
| 585 | {} |
| 586 | shared_state(exceptional_ptr const& ex): |
| 587 | detail::shared_state_base(ex), result() |
| 588 | {} |
| 589 | |
| 590 | // locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193 |
| 591 | BOOST_THREAD_DO_CONTINUATION |
| 592 | |
| 593 | void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock) |
| 594 | { |
| 595 | #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL |
| 596 | result = result_; |
| 597 | #else |
| 598 | result.reset(new T(result_)); |
| 599 | #endif |
| 600 | this->mark_finished_internal(lock); |
| 601 | } |
| 602 | |
| 603 | void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock) |
| 604 | { |
| 605 | #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL |
| 606 | result = boost::move(result_); |
| 607 | #elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES |
| 608 | result.reset(new T(boost::move(result_))); |
| 609 | #else |
| 610 | result.reset(new T(static_cast<rvalue_source_type>(result_))); |
| 611 | #endif |
| 612 | this->mark_finished_internal(lock); |
| 613 | } |
| 614 | |