Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r84978 - in trunk: boost/thread libs/thread/test libs/thread/test/sync/futures/future libs/thread/test/sync/futures/shared_future
From: vicente.botet_at_[hidden]
Date: 2013-07-07 16:36:06


Author: viboes
Date: 2013-07-07 16:36:05 EDT (Sun, 07 Jul 2013)
New Revision: 84978
URL: http://svn.boost.org/trac/boost/changeset/84978

Log:
Thread: fix issue with continuation's future parameter which must taken by value.

Text files modified:
   trunk/boost/thread/future.hpp | 164 +++++++++++++++++++--------------------
   trunk/libs/thread/test/Jamfile.v2 | 1
   trunk/libs/thread/test/sync/futures/future/then_pass.cpp | 5
   trunk/libs/thread/test/sync/futures/shared_future/then_pass.cpp | 4
   4 files changed, 86 insertions(+), 88 deletions(-)

Modified: trunk/boost/thread/future.hpp
==============================================================================
--- trunk/boost/thread/future.hpp Sun Jul 7 14:52:52 2013 (r84977)
+++ trunk/boost/thread/future.hpp 2013-07-07 16:36:05 EDT (Sun, 07 Jul 2013) (r84978)
@@ -1399,18 +1399,18 @@
 
         template <class F, class Rp, class Fp>
         BOOST_THREAD_FUTURE<Rp>
- make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c);
+ make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
 
         template <class F, class Rp, class Fp>
         BOOST_THREAD_FUTURE<Rp>
- make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c);
+ make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
 #endif
 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
         template<typename F, typename Rp>
         struct future_unwrap_shared_state;
         template <class F, class Rp>
         inline BOOST_THREAD_FUTURE<Rp>
- make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, F& f);
+ make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
 #endif
     }
 
@@ -1431,18 +1431,18 @@
 
         template <class F, class Rp, class Fp>
         friend BOOST_THREAD_FUTURE<Rp>
- detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c);
+ detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
 
         template <class F, class Rp, class Fp>
         friend BOOST_THREAD_FUTURE<Rp>
- detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c);
+ detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
 #endif
 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
         template<typename F, typename Rp>
         friend struct detail::future_unwrap_shared_state;
         template <class F, class Rp>
         friend BOOST_THREAD_FUTURE<Rp>
- detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, F& f);
+ detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
 #endif
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
         template <class> friend class packaged_task; // todo check if this works in windows
@@ -1470,7 +1470,7 @@
     public:
         BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
         typedef future_state::state state;
- typedef R value_type;
+ typedef R value_type; // EXTENSION
 
         BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
 
@@ -1480,7 +1480,7 @@
         base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
         {
         }
- inline BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other);
+ inline BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
 
         BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
         {
@@ -1546,7 +1546,7 @@
 
         template <typename R2>
         typename disable_if< is_void<R2>, move_dest_type>::type
- get_or(R2 const& v)
+ get_or(R2 const& v) // EXTENSION
         {
             if(!this->future_)
             {
@@ -1578,18 +1578,18 @@
 // inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&));
 //#endif
         template<typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE&)>::type>
- then(BOOST_THREAD_FWD_REF(F) func);
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
+ then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
         template<typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE&)>::type>
- then(launch policy, BOOST_THREAD_FWD_REF(F) func);
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
+ then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
 
         template <typename R2>
         inline typename disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
- fallback_to(BOOST_THREAD_RV_REF(R2) v);
+ fallback_to(BOOST_THREAD_RV_REF(R2) v); // EXTENSION
         template <typename R2>
         inline typename disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
- fallback_to(R2 const& v);
+ fallback_to(R2 const& v); // EXTENSION
 
 #endif
 
@@ -1626,18 +1626,18 @@
 
             template <class F, class Rp, class Fp>
             friend BOOST_THREAD_FUTURE<Rp>
- detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c);
+ detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
 
             template <class F, class Rp, class Fp>
             friend BOOST_THREAD_FUTURE<Rp>
- detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c);
+ detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
     #endif
 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
             template<typename F, typename Rp>
             friend struct detail::future_unwrap_shared_state;
         template <class F, class Rp>
         friend BOOST_THREAD_FUTURE<Rp>
- detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, F& f);
+ detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
 #endif
     #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
             template <class> friend class packaged_task; // todo check if this works in windows
@@ -1665,7 +1665,7 @@
         public:
             BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
             typedef future_state::state state;
- typedef R value_type;
+ typedef R value_type; // EXTENSION
 
             BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
 
@@ -1716,7 +1716,7 @@
     #endif
                 return fut_->get();
             }
- move_dest_type get_or(BOOST_THREAD_RV_REF(R) v)
+ move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
             {
                 if(!this->future_)
                 {
@@ -1731,7 +1731,7 @@
                 else return boost::move(v);
             }
 
- move_dest_type get_or(R const& v)
+ move_dest_type get_or(R const& v) // EXTENSION
             {
                 if(!this->future_)
                 {
@@ -1759,17 +1759,17 @@
     // inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&));
     //#endif
             template<typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE&)>::type>
- then(BOOST_THREAD_FWD_REF(F) func);
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
+ then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
             template<typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE&)>::type>
- then(launch policy, BOOST_THREAD_FWD_REF(F) func);
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
+ then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
     #endif
 
     #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
             inline
             BOOST_THREAD_FUTURE<R2>
- unwrap();
+ unwrap(); // EXTENSION
     #endif
 
   };
@@ -1792,11 +1792,11 @@
 
         template <class F, class Rp, class Fp>
         friend BOOST_THREAD_FUTURE<Rp>
- detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c);
+ detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
 
         template <class F, class Rp, class Fp>
         friend BOOST_THREAD_FUTURE<Rp>
- detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c);
+ detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
 #endif
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
         template <class> friend class packaged_task;// todo check if this works in windows
@@ -1809,7 +1809,7 @@
 
     public:
         BOOST_THREAD_MOVABLE(shared_future)
- typedef R value_type;
+ typedef R value_type; // EXTENSION
 
         shared_future(shared_future const& other):
         base_type(other)
@@ -1867,7 +1867,7 @@
 
         template <typename R2>
         typename disable_if< is_void<R2>, typename detail::shared_state<R>::shared_future_get_result_type>::type
- get_or(BOOST_THREAD_RV_REF(R2) v)
+ get_or(BOOST_THREAD_RV_REF(R2) v) // EXTENSION
         {
             if(!this->future_)
             {
@@ -1893,11 +1893,11 @@
 // inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(shared_future&));
 //#endif
         template<typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future&)>::type>
- then(BOOST_THREAD_FWD_REF(F) func);
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
+ then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
         template<typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future&)>::type>
- then(launch policy, BOOST_THREAD_FWD_REF(F) func);
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
+ then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
 #endif
 //#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
 // inline
@@ -3118,7 +3118,7 @@
             task = task_ptr(new task_shared_state_type(boost::forward<F>(f)));
 #else
             typedef detail::task_shared_state<F,R()> task_shared_state_type;
- task = task_ptr(new task_shared_state_type(boost::move<F>(f))); // TODO forward
+ task = task_ptr(new task_shared_state_type(boost::move(f))); // TODO forward
 #endif
 #else
             typedef detail::task_shared_state<F,R> task_shared_state_type;
@@ -3714,9 +3714,9 @@
 
     public:
       future_async_continuation_shared_state(
- F& f, BOOST_THREAD_FWD_REF(Fp) c
+ BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
           ) :
- parent(f.future_),
+ parent(boost::move(f)),
       continuation(boost::move(c))
       {
       }
@@ -3731,7 +3731,7 @@
       {
         try
         {
- that->mark_finished_with_result(that->continuation(that->parent));
+ that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
         }
 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
         catch(thread_interrupted& )
@@ -3754,10 +3754,9 @@
 
     public:
       future_async_continuation_shared_state(
- F& f, BOOST_THREAD_FWD_REF(Fp) c
+ BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
           ) :
- parent(f.future_),
- //continuation(boost::forward<Fp>(c)
+ parent(boost::move(f)),
       continuation(boost::move(c))
       {
       }
@@ -3772,7 +3771,7 @@
       {
         try
         {
- that->continuation(that->parent);
+ that->continuation(boost::move(that->parent));
           that->mark_finished_with_result();
         }
 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -3800,10 +3799,9 @@
 
     public:
       future_deferred_continuation_shared_state(
- F& f, BOOST_THREAD_FWD_REF(Fp) c
+ BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
           ) :
- parent(f.future_),
- //continuation(boost::forward<Fp>(c)
+ parent(boost::move(f)),
           continuation(boost::move(c))
       {
         this->set_deferred();
@@ -3817,7 +3815,7 @@
       virtual void execute(boost::unique_lock<boost::mutex>& lck) {
         try
         {
- this->mark_finished_with_result_internal(continuation(parent), lck);
+ this->mark_finished_with_result_internal(continuation(boost::move(parent)), lck);
         }
         catch (...)
         {
@@ -3834,9 +3832,9 @@
 
     public:
       future_deferred_continuation_shared_state(
- F& f, BOOST_THREAD_FWD_REF(Fp) c
+ BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
           ):
- parent(f.future_),
+ parent(boost::move(f)),
           continuation(boost::move(c))
       {
         this->set_deferred();
@@ -3849,7 +3847,7 @@
       virtual void execute(boost::unique_lock<boost::mutex>& lck) {
         try
         {
- continuation(parent);
+ continuation(boost::move(parent));
           this->mark_finished_with_result_internal(lck);
         }
         catch (...)
@@ -3866,12 +3864,12 @@
     BOOST_THREAD_FUTURE<Rp>
     make_future_deferred_continuation_shared_state(
         boost::unique_lock<boost::mutex> &lock,
- F& f, BOOST_THREAD_FWD_REF(Fp) c
+ BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
         )
     {
       shared_ptr<future_deferred_continuation_shared_state<F, Rp, Fp> >
- h(new future_deferred_continuation_shared_state<F, Rp, Fp>(f, boost::forward<Fp>(c)));
- f.future_->set_continuation_ptr(h, lock);
+ h(new future_deferred_continuation_shared_state<F, Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
+ h->parent.future_->set_continuation_ptr(h, lock);
       return BOOST_THREAD_FUTURE<Rp>(h);
     }
 
@@ -3881,12 +3879,12 @@
     template<typename F, typename Rp, typename Fp>
     BOOST_THREAD_FUTURE<Rp>
     make_future_async_continuation_shared_state(
- boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c
+ boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
         )
     {
       shared_ptr<future_async_continuation_shared_state<F,Rp, Fp> >
- h(new future_async_continuation_shared_state<F,Rp, Fp>(f, boost::forward<Fp>(c)));
- f.future_->set_continuation_ptr(h, lock);
+ h(new future_async_continuation_shared_state<F,Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
+ h->parent.future_->set_continuation_ptr(h, lock);
 
       return BOOST_THREAD_FUTURE<Rp>(h);
     }
@@ -3900,31 +3898,31 @@
 
   template <typename R>
   template <typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
   BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func)
   {
 
- typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type future_type;
+ typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
     BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
 
     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
     if (int(policy) & int(launch::async))
     {
       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
               )));
     }
     else if (int(policy) & int(launch::deferred))
     {
       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
               )));
     }
     else
     {
       //BOOST_THREAD_ASSERT_PRECONDITION(false && "invalid launch parameter", std::logic_error("invalid launch parameter"));
       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
               )));
 
     }
@@ -3932,32 +3930,32 @@
   }
   template <typename R>
   template <typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
   BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func)
   {
 
- typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type future_type;
+ typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
     BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
 
     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
     if (int(this->launch_policy()) & int(launch::async))
     {
       return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
       );
     }
     else if (int(this->launch_policy()) & int(launch::deferred))
     {
       this->future_->wait_internal(lock);
       return boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
       );
     }
     else
     {
       //BOOST_THREAD_ASSERT_PRECONDITION(false && "invalid launch parameter", std::logic_error("invalid launch parameter"));
       return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
       );
     }
   }
@@ -4018,42 +4016,42 @@
 
   template <typename R>
   template <typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>&)>::type>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
   shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func)
   {
 
- typedef typename boost::result_of<F(shared_future<R>&)>::type future_type;
+ typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
     BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
 
     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
     if (int(policy) & int(launch::async))
     {
       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
               )));
     }
     else if (int(policy) & int(launch::deferred))
     {
       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
               )));
     }
     else
     {
       //BOOST_THREAD_ASSERT_PRECONDITION(false && "invalid launch parameter", std::logic_error("invalid launch parameter"));
       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
               )));
     }
 
   }
   template <typename R>
   template <typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>&)>::type>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
   shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func)
   {
 
- typedef typename boost::result_of<F(shared_future<R>&)>::type future_type;
+ typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
 
     BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
 
@@ -4061,21 +4059,21 @@
     if (int(this->launch_policy()) & int(launch::async))
     {
       return boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
       );
     }
     else if (int(this->launch_policy()) & int(launch::deferred))
     {
       this->future_->wait_internal(lock);
       return boost::detail::make_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
       );
     }
     else
     {
       //BOOST_THREAD_ASSERT_PRECONDITION(false && "invalid launch parameter", std::logic_error("invalid launch parameter"));
       return boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
- lock, *this, boost::forward<F>(func)
+ lock, boost::move(*this), boost::forward<F>(func)
       );
     }
   }
@@ -4090,7 +4088,7 @@
       : value_(boost::move(v))
       {}
 
- T operator()(BOOST_THREAD_FUTURE<T>& fut)
+ T operator()(BOOST_THREAD_FUTURE<T> fut)
       {
         return fut.get_or(boost::move(value_));
 
@@ -4105,7 +4103,7 @@
       : value_(v)
       {}
 
- T operator()(BOOST_THREAD_FUTURE<T>& fut)
+ T operator()(BOOST_THREAD_FUTURE<T> fut)
       {
         return fut.get_or(value_);
 
@@ -4148,9 +4146,9 @@
       F parent;
     public:
       explicit future_unwrap_shared_state(
- F& f
+ BOOST_THREAD_RV_REF(F) f
           ) :
- parent(f.future_)
+ parent(boost::move(f))
       {
       }
       virtual void wait(bool ) // todo see if rethrow must be used
@@ -4168,13 +4166,13 @@
 
     template <class F, class Rp>
     BOOST_THREAD_FUTURE<Rp>
- make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, F& f)
+ make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f)
     {
       shared_ptr<future_unwrap_shared_state<F, Rp> >
       //shared_ptr<basic_future<Rp> >
       //typename boost::detail::basic_future<Rp>::future_ptr
- h(new future_unwrap_shared_state<F, Rp>(f));
- f.future_->set_continuation_ptr(h, lock);
+ h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
+ h->parent.future_->set_continuation_ptr(h, lock);
       return BOOST_THREAD_FUTURE<Rp>(h);
     }
   }
@@ -4191,7 +4189,7 @@
   {
     BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
- return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, *this);
+ return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
   }
 #endif
 }

Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 Sun Jul 7 14:52:52 2013 (r84977)
+++ trunk/libs/thread/test/Jamfile.v2 2013-07-07 16:36:05 EDT (Sun, 07 Jul 2013) (r84978)
@@ -782,7 +782,6 @@
           #[ thread-run test_7720.cpp ]
           #[ thread-run test_7666.cpp ]
           #[ thread-run test_7755.cpp ]
- #[ thread-run ../example/unwrap.cpp ]
           #[ thread-run ../example/perf_condition_variable.cpp ]
           #[ thread-run ../example/perf_shared_mutex.cpp ]
           #[ thread-run ../example/std_async_test.cpp ]

Modified: trunk/libs/thread/test/sync/futures/future/then_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/future/then_pass.cpp Sun Jul 7 14:52:52 2013 (r84977)
+++ trunk/libs/thread/test/sync/futures/future/then_pass.cpp 2013-07-07 16:36:05 EDT (Sun, 07 Jul 2013) (r84978)
@@ -29,7 +29,7 @@
   return 1;
 }
 
-int p2(boost::future<int>& f)
+int p2(boost::future<int> f)
 {
   BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
   BOOST_TEST(f.valid());
@@ -39,7 +39,7 @@
   return 2 * i;
 }
 
-void p3(boost::future<int>& f)
+void p3(boost::future<int> f)
 {
   BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
   BOOST_TEST(f.valid());
@@ -57,6 +57,7 @@
     BOOST_TEST(f1.valid());
     boost::future<int> f2 = f1.then(&p2);
     BOOST_TEST(f2.valid());
+ BOOST_TEST(! f1.valid());
     try
     {
       BOOST_TEST(f2.get()==2);

Modified: trunk/libs/thread/test/sync/futures/shared_future/then_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/shared_future/then_pass.cpp Sun Jul 7 14:52:52 2013 (r84977)
+++ trunk/libs/thread/test/sync/futures/shared_future/then_pass.cpp 2013-07-07 16:36:05 EDT (Sun, 07 Jul 2013) (r84978)
@@ -28,7 +28,7 @@
   return 1;
 }
 
-int p2(boost::shared_future<int>& f)
+int p2(boost::shared_future<int> f)
 {
   BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
   BOOST_TEST(f.valid());
@@ -38,7 +38,7 @@
   return 2 * i;
 }
 
-void p3(boost::shared_future<int>& f)
+void p3(boost::shared_future<int> f)
 {
   BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
   BOOST_TEST(f.valid());


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk