$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r84541 - in trunk: boost/thread libs/thread/example
From: vicente.botet_at_[hidden]
Date: 2013-05-28 16:25:35
Author: viboes
Date: 2013-05-28 16:25:34 EDT (Tue, 28 May 2013)
New Revision: 84541
URL: http://svn.boost.org/trac/boost/changeset/84541
Log:
Thread: Added shared_future::then.
Text files modified: 
   trunk/boost/thread/future.hpp             |   121 +++++++++++++++++++++++++++++++++++++-- 
   trunk/libs/thread/example/future_then.cpp |    39 ++++++++++++                            
   2 files changed, 151 insertions(+), 9 deletions(-)
Modified: trunk/boost/thread/future.hpp
==============================================================================
--- trunk/boost/thread/future.hpp	(original)
+++ trunk/boost/thread/future.hpp	2013-05-28 16:25:34 EDT (Tue, 28 May 2013)
@@ -1430,6 +1430,14 @@
         friend struct detail::future_async_continuation;
         template <typename, typename, typename>
         friend struct detail::future_deferred_continuation;
+
+        template <class F, class Rp, class Fp>
+        friend BOOST_THREAD_FUTURE<Rp>
+        detail::make_future_async_continuation(boost::unique_lock<boost::mutex> &lock, 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(boost::unique_lock<boost::mutex> &lock, 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
@@ -1446,15 +1454,6 @@
         friend BOOST_THREAD_FUTURE<Rp>
         detail::make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f);
 
-#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
-        template <class F, class Rp, class Fp>
-        friend BOOST_THREAD_FUTURE<Rp>
-        detail::make_future_async_continuation(boost::unique_lock<boost::mutex> &lock, 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(boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c);
-#endif
 
         typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
 
@@ -1554,6 +1553,20 @@
         friend class detail::future_waiter;
         friend class promise<R>;
 
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+        template <typename, typename, typename>
+        friend struct detail::future_async_continuation;
+        template <typename, typename, typename>
+        friend struct detail::future_deferred_continuation;
+
+        template <class F, class Rp, class Fp>
+        friend BOOST_THREAD_FUTURE<Rp>
+        detail::make_future_async_continuation(boost::unique_lock<boost::mutex> &lock, 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(boost::unique_lock<boost::mutex> &lock, 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
 #else
@@ -1620,7 +1633,26 @@
 
             return this->future_->get_sh();
         }
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
 
+//        template<typename F>
+//        auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+//        template<typename F>
+//        auto then(launch, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+
+//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+//        template<typename RF>
+//        inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(shared_future&));
+//        template<typename RF>
+//        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);
+        template<typename F>
+        inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future&)>::type>
+        then(launch policy, BOOST_THREAD_FWD_REF(F) func);
+#endif
     };
 
     BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
@@ -3822,6 +3854,8 @@
       return BOOST_THREAD_FUTURE<future_type>();
     }
   }
+
+
 //#if 0 && defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
 //  template <typename R>
 //  template<typename RF>
@@ -3875,6 +3909,75 @@
 //  }
 //#endif
 
+  template <typename R>
+  template <typename F>
+  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;
+
+    if (this->future_==0)
+    {
+      // fixme what to do when the future has no associated state?
+      return BOOST_THREAD_FUTURE<future_type>();
+    }
+
+    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_future<R>, future_type, F>(
+                  lock, *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_future<R>, future_type, F>(
+                  lock, *this, boost::forward<F>(func)
+              )));
+    }
+    else
+    {
+      // fixme what to do when the policy is invalid?
+      return BOOST_THREAD_FUTURE<future_type>();
+    }
+
+  }
+  template <typename R>
+  template <typename F>
+  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;
+
+    if (this->future_==0)
+    {
+      //BOOST_THREAD_LOG << "ERROR future::then " << this << BOOST_THREAD_END_LOG;
+      // fixme what to do when the future has no associated state?
+      return BOOST_THREAD_FUTURE<future_type>();
+    }
+
+    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_future<R>, future_type, F>(
+          lock, *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_future<R>, future_type, F>(
+          lock, *this, boost::forward<F>(func)
+      );
+    }
+    else
+    {
+      // fixme what to do when the policy is invalid?
+      return BOOST_THREAD_FUTURE<future_type>();
+    }
+  }
 #endif
 
 }
Modified: trunk/libs/thread/example/future_then.cpp
==============================================================================
--- trunk/libs/thread/example/future_then.cpp	(original)
+++ trunk/libs/thread/example/future_then.cpp	2013-05-28 16:25:34 EDT (Tue, 28 May 2013)
@@ -38,10 +38,30 @@
   }
   BOOST_THREAD_LOG << "P2>" << BOOST_THREAD_END_LOG;
 }
+int p2s(boost::shared_future<int>& f)
+{
+  BOOST_THREAD_LOG << "<P2" << BOOST_THREAD_END_LOG;
+  try
+  {
+    return 2 * f.get();
+  }
+  catch (std::exception& ex)
+  {
+    BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+    BOOST_ASSERT(false);
+  }
+  catch (...)
+  {
+    BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+    BOOST_ASSERT(false);
+  }
+  BOOST_THREAD_LOG << "P2>" << BOOST_THREAD_END_LOG;
+}
 
 int main()
 {
   BOOST_THREAD_LOG << "<MAIN" << BOOST_THREAD_END_LOG;
+  {
   try
   {
     boost::future<int> f1 = boost::async(boost::launch::async, &p1);
@@ -58,6 +78,25 @@
     BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
     return 2;
   }
+  }
+  {
+  try
+  {
+    boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+    boost::future<int> f2 = f1.then(&p2s);
+    (void)f2.get();
+  }
+  catch (std::exception& ex)
+  {
+    BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+    return 1;
+  }
+  catch (...)
+  {
+    BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+    return 2;
+  }
+  }
   BOOST_THREAD_LOG << "MAIN>" << BOOST_THREAD_END_LOG;
   return 0;
 }