Index: boost/thread/future.hpp =================================================================== --- boost/thread/future.hpp (revision 82757) +++ boost/thread/future.hpp (working copy) @@ -509,7 +509,8 @@ typedef T const& source_reference_type; struct dummy; typedef typename boost::mpl::if_,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type; - typedef typename boost::mpl::if_,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type; + //typedef typename boost::mpl::if_,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type; + typedef T move_dest_type; #elif defined BOOST_THREAD_USES_MOVE typedef T& source_reference_type; typedef typename boost::mpl::if_,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type; @@ -627,7 +628,8 @@ move_dest_type get() { wait(); - return static_cast(*result); + //return static_cast(*result); + return boost::move(*result); } shared_future_get_result_type get_sh() @@ -658,7 +660,9 @@ { throw_exception(promise_already_satisfied()); } - future_traits::init(result,result_); + //future_traits::init(result,result_); + result.reset(new T(result_)); + this->is_constructed = true; get_current_thread_data()->make_ready_at_thread_exit(shared_from_this()); } @@ -1417,7 +1421,7 @@ BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT { - base_type::operator=(boost::move(static_cast(BOOST_THREAD_RV(other)))); + this->base_type::operator=(boost::move(static_cast(BOOST_THREAD_RV(other)))); return *this; } @@ -2077,6 +2081,7 @@ #endif } + #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) virtual void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0; void apply(BOOST_THREAD_RV_REF(ArgTypes) ... args) @@ -2241,7 +2246,9 @@ { try { - this->set_value_at_thread_exit(f()); + //this->set_value_at_thread_exit(f()); + R r = f(); + this->set_value_at_thread_exit(boost::move(r)); } #endif #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS @@ -2725,7 +2732,7 @@ else if(!future_obtained) { future_obtained=true; - return BOOST_THREAD_FUTURE(task); + return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE(task)); } else { @@ -2858,7 +2865,7 @@ { packaged_task_type pt( f ); - BOOST_THREAD_FUTURE ret = pt.get_future(); + BOOST_THREAD_FUTURE ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future()); #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) boost::thread( boost::move(pt), boost::forward(args)... ).detach(); #else @@ -2912,8 +2919,8 @@ typedef typename boost::result_of::type()>::type R; typedef packaged_task packaged_task_type; - typedef detail::async_func::type> BF; - typedef typename BF::result_type Rp; + //typedef detail::async_func::type> BF; + //typedef typename BF::result_type Rp; #endif #else @@ -2924,8 +2931,8 @@ typedef typename boost::result_of::type()>::type R; typedef packaged_task packaged_task_type; - typedef detail::async_func::type> BF; - typedef typename BF::result_type Rp; + //typedef detail::async_func::type> BF; + //typedef typename BF::result_type Rp; #endif if (int(policy) & int(launch::async)) Index: libs/thread/test/sync/futures/async/async_pass.cpp =================================================================== --- libs/thread/test/sync/futures/async/async_pass.cpp (revision 82706) +++ libs/thread/test/sync/futures/async/async_pass.cpp (working copy) @@ -25,6 +25,7 @@ //#define BOOST_THREAD_VERSION 3 #define BOOST_THREAD_VERSION 4 +#include #include #include #include @@ -56,20 +57,37 @@ public: typedef int result_type; + int value; + BOOST_THREAD_MOVABLE_ONLY(MoveOnly) MoveOnly() { + value=0; } MoveOnly(BOOST_THREAD_RV_REF(MoveOnly)) - {} + { + value=1; + } + MoveOnly& operator=(BOOST_THREAD_RV_REF(MoveOnly)) + { + value=2; + return *this; + } int operator()() { boost::this_thread::sleep_for(ms(200)); return 3; } + template + friend OS& operator<<(OS& os, MoveOnly const& v) + { + os << v.value; + return os; + } }; + int f0() { boost::this_thread::sleep_for(ms(200)); @@ -89,6 +107,19 @@ boost::this_thread::sleep_for(ms(200)); } +boost::interprocess::unique_ptr > f3_0() +{ + boost::this_thread::sleep_for(ms(200)); + boost::interprocess::unique_ptr > r((new int(3))); + return boost::move(r); +} +MoveOnly f3_1() +{ + boost::this_thread::sleep_for(ms(200)); + MoveOnly r; + return boost::move(r); +} + boost::interprocess::unique_ptr > f3(int i) { boost::this_thread::sleep_for(ms(200)); @@ -114,7 +145,6 @@ BOOST_TEST(f.get() == 3); Clock::time_point t1 = Clock::now(); BOOST_TEST(t1 - t0 < ms(200)); - std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl; } catch (std::exception& ex) { std::cout << __FILE__ <<"["<<__LINE__<<"]"< f = boost::async(&f3_1); + boost::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + BOOST_TEST(f.get().value == 1); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(t1 - t0 < ms(200)); + } catch (std::exception& ex) { + std::cout << __FILE__ <<"["<<__LINE__<<"]"< f; + f = boost::async(&f3_1); + boost::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + BOOST_TEST(f.get().value == 1); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(t1 - t0 < ms(200)); + } catch (std::exception& ex) { + std::cout << __FILE__ <<"["<<__LINE__<<"]"< > > f = boost::async(&f3_0); + boost::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + std::cout << __FILE__ <<"["<<__LINE__<<"] "<< std::endl; + BOOST_TEST(*f.get() == 3); + std::cout << __FILE__ <<"["<<__LINE__<<"] "<< std::endl; + Clock::time_point t1 = Clock::now(); + BOOST_TEST(t1 - t0 < ms(200)); + std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl; + } catch (std::exception& ex) { + std::cout << __FILE__ <<"["<<__LINE__<<"]"<