Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r82808 - in trunk: boost/thread libs/thread/test/sync/futures/async
From: vicente.botet_at_[hidden]
Date: 2013-02-10 13:14:50


Author: viboes
Date: 2013-02-10 13:14:49 EST (Sun, 10 Feb 2013)
New Revision: 82808
URL: http://svn.boost.org/trac/boost/changeset/82808

Log:
Thread: fix some issues with futures of MoveOnly types + complete the variadic async function.
Text files modified:
   trunk/boost/thread/future.hpp | 326 ++++++++++++++++++++++++++++++++++-----
   trunk/libs/thread/test/sync/futures/async/async_pass.cpp | 135 +++++++++++++++-
   2 files changed, 409 insertions(+), 52 deletions(-)

Modified: trunk/boost/thread/future.hpp
==============================================================================
--- trunk/boost/thread/future.hpp (original)
+++ trunk/boost/thread/future.hpp 2013-02-10 13:14:49 EST (Sun, 10 Feb 2013)
@@ -505,15 +505,19 @@
         struct future_traits
         {
             typedef boost::scoped_ptr<T> storage_type;
+ struct dummy;
 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
             typedef T const& source_reference_type;
- struct dummy;
- typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
- typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type;
+ //typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
+ typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
+ //typedef typename boost::mpl::if_<boost::is_fundamental<T>,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::has_move_emulation_enabled<T>,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type;
- typedef typename boost::mpl::if_<boost::has_move_emulation_enabled<T>,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
+ typedef typename boost::mpl::if_c<boost::is_fundamental<T>::value,T,T&>::type source_reference_type;
+ //typedef typename boost::mpl::if_c<boost::is_fundamental<T>::value,T,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
+ //typedef typename boost::mpl::if_c<boost::enable_move_utility_emulation<T>::value,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
+ typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
+ typedef T move_dest_type;
 #else
             typedef T& source_reference_type;
             typedef typename boost::mpl::if_<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type;
@@ -529,7 +533,11 @@
 
             static void init(storage_type& storage,rvalue_source_type t)
             {
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ storage.reset(new T(boost::forward<T>(t)));
+#else
               storage.reset(new T(static_cast<rvalue_source_type>(t)));
+#endif
             }
 
             static void cleanup(storage_type& storage)
@@ -607,7 +615,11 @@
 
             void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
             {
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ future_traits<T>::init(result,boost::forward<T>(result_));
+#else
                 future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
+#endif
                 mark_finished_internal(lock);
             }
 
@@ -620,20 +632,27 @@
             void mark_finished_with_result(rvalue_source_type result_)
             {
                 boost::unique_lock<boost::mutex> lock(mutex);
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ mark_finished_with_result_internal(boost::forward<T>(result_), lock);
+#else
                 mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
+#endif
+
             }
 
 
             move_dest_type get()
             {
                 wait();
- return static_cast<move_dest_type>(*result);
+ //return static_cast<move_dest_type>(*result);
+ return boost::move(*result);
             }
 
             shared_future_get_result_type get_sh()
             {
                 wait();
- return static_cast<shared_future_get_result_type>(*result);
+ //return static_cast<shared_future_get_result_type>(*result);
+ return *result;
             }
 
             // todo move this to detail::future_object_base
@@ -651,23 +670,26 @@
             }
 
 
- void set_value_at_thread_exit(const T & result_)
+ void set_value_at_thread_exit(source_reference_type result_)
             {
               unique_lock<boost::mutex> lk(this->mutex);
               if (this->has_value(lk))
               {
                   throw_exception(promise_already_satisfied());
               }
- future_traits<T>::init(result,result_);
+ //future_traits<T>::init(result,result_);
+ result.reset(new T(result_));
+
               this->is_constructed = true;
               get_current_thread_data()->make_ready_at_thread_exit(shared_from_this());
             }
- void set_value_at_thread_exit(BOOST_THREAD_RV_REF(T) result_)
+ void set_value_at_thread_exit(rvalue_source_type result_)
             {
               unique_lock<boost::mutex> lk(this->mutex);
               if (this->has_value(lk))
                   throw_exception(promise_already_satisfied());
               result.reset(new T(boost::move(result_)));
+ //result.reset(new T(boost::forward<T>(result_)));
               //future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
               this->is_constructed = true;
               get_current_thread_data()->make_ready_at_thread_exit(shared_from_this());
@@ -683,11 +705,11 @@
         struct future_object<T&>:
             detail::future_object_base
         {
- typedef typename future_traits<T>::storage_type storage_type;
- typedef typename future_traits<T>::source_reference_type source_reference_type;
- typedef typename future_traits<T>::rvalue_source_type rvalue_source_type;
- typedef typename future_traits<T>::move_dest_type move_dest_type;
- typedef typename future_traits<T>::shared_future_get_result_type shared_future_get_result_type;
+ typedef typename future_traits<T&>::storage_type storage_type;
+ typedef typename future_traits<T&>::source_reference_type source_reference_type;
+ typedef typename future_traits<T&>::rvalue_source_type rvalue_source_type;
+ typedef typename future_traits<T&>::move_dest_type move_dest_type;
+ typedef typename future_traits<T&>::shared_future_get_result_type shared_future_get_result_type;
 
             T* result;
 
@@ -699,7 +721,7 @@
             {
             }
 
- void mark_finished_with_result_internal(T& result_, boost::unique_lock<boost::mutex>& lock)
+ void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
             {
                 //future_traits<T>::init(result,result_);
                 result= &result_;
@@ -708,11 +730,11 @@
 
 // void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
 // {
-// future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
+// future_traits<T&>::init(result,static_cast<rvalue_source_type>(result_));
 // mark_finished_internal(lock);
 // }
 
- void mark_finished_with_result(T& result_)
+ void mark_finished_with_result(source_reference_type result_)
             {
                 boost::unique_lock<boost::mutex> lock(mutex);
                 mark_finished_with_result_internal(result_, lock);
@@ -866,7 +888,9 @@
               boost::unique_lock<boost::mutex> lock(this->mutex);
               this->wait_internal(lock);
 
- return static_cast<move_dest_type>(*(this->result));
+ //return static_cast<move_dest_type>(*(this->result));
+ return boost::move<Rp>(*(this->result));
+
           }
 
           static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f)
@@ -1417,7 +1441,7 @@
 
         BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
         {
- base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
+ this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
             return *this;
         }
 
@@ -1676,7 +1700,11 @@
             {
                 boost::throw_exception(promise_already_satisfied());
             }
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ future_->mark_finished_with_result_internal(boost::forward<R>(r), lock);
+#else
             future_->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r), lock);
+#endif
         }
 
         void set_exception(boost::exception_ptr p)
@@ -2077,6 +2105,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)
@@ -2186,7 +2215,102 @@
             {
                 try
                 {
- this->mark_finished_with_result(f());
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ R res((f()));
+ this->mark_finished_with_result(boost::move(res));
+#else
+ this->mark_finished_with_result(f());
+#endif
+
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->mark_interrupted_finish();
+ }
+#endif
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename F, typename R, typename ...ArgTypes>
+ struct task_object<F, R&(ArgTypes...)>:
+ task_base<R&(ArgTypes...)>
+#else
+ template<typename F, typename R>
+ struct task_object<F, R&()>:
+ task_base<R&()>
+#endif
+#else
+ template<typename F, typename R>
+ struct task_object<F,R&>:
+ task_base<R&>
+#endif
+ {
+ private:
+ task_object(task_object&);
+ public:
+ F f;
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ task_object(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::forward<F>(f_))
+ {}
+#else
+ task_object(F const& f_):
+ f(f_)
+ {}
+ task_object(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::move(f_)) // TODO forward
+ {}
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f());
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->set_interrupted_at_thread_exit();
+ }
+#endif
+ catch(...)
+ {
+ this->set_exception_at_thread_exit(current_exception());
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_run()
+ {
+ try
+ {
+ R& res((f()));
+ this->mark_finished_with_result(res);
                 }
 #endif
 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -2202,6 +2326,7 @@
             }
         };
 
+
 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
 
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
@@ -2241,7 +2366,91 @@
                 {
                     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
+ catch(thread_interrupted& )
+ {
+ this->set_interrupted_at_thread_exit();
+ }
+#endif
+ catch(...)
+ {
+ this->set_exception_at_thread_exit(current_exception());
+ }
+ }
+
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_run()
+ {
+ try
+ {
+ //this->set_value_at_thread_exit(f());
+ R res((f()));
+ this->mark_finished_with_result(boost::move(res));
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->mark_interrupted_finish();
+ }
+#endif
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename R, typename ...ArgTypes>
+ struct task_object<R& (*)(ArgTypes...), R&(ArgTypes...)>:
+ task_base<R&(ArgTypes...)>
+#else
+ template<typename R>
+ struct task_object<R& (*)(), R&()>:
+ task_base<R&()>
+#endif
+#else
+ template<typename R>
+ struct task_object<R& (*)(), R&> :
+ task_base<R&>
+#endif
+ {
+ private:
+ task_object(task_object&);
+ public:
+ R& (*f)();
+ task_object(R& (*f_)()):
+ f(f_)
+ {}
+
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f());
                     }
 #endif
 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -2691,7 +2900,11 @@
         {
 
             // todo use forward
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ packaged_task temp(boost::move(other));
+#else
             packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
+#endif
             swap(temp);
             return *this;
         }
@@ -2725,6 +2938,7 @@
             else if(!future_obtained)
             {
                 future_obtained=true;
+ //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<R>(task));
                 return BOOST_THREAD_FUTURE<R>(task);
             }
             else
@@ -2827,6 +3041,11 @@
 
     ////////////////////////////////
     // template <class F, class... ArgTypes>
+ // future<R> async(launch policy, F&&, ArgTypes&&...);
+ ////////////////////////////////
+
+ ////////////////////////////////
+ // template <class F, class... ArgTypes>
     // future<R> async(F&&, ArgTypes&&...);
     ////////////////////////////////
 
@@ -2858,7 +3077,7 @@
             {
               packaged_task_type pt( f );
 
- BOOST_THREAD_FUTURE<R> ret = pt.get_future();
+ BOOST_THREAD_FUTURE<R> 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<ArgTypes>(args)... ).detach();
 #else
@@ -2878,12 +3097,6 @@
             }
         }
 
- template <class R>
- BOOST_THREAD_FUTURE<R>
- async(R(*f)())
- {
- return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
- }
 #endif
 
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
@@ -2912,9 +3125,6 @@
           typedef typename boost::result_of<typename decay<F>::type()>::type R;
           typedef packaged_task<R()> packaged_task_type;
 
- typedef detail::async_func<typename decay<F>::type> BF;
- typedef typename BF::result_type Rp;
-
   #endif
 #else
         template <class F>
@@ -2924,8 +3134,6 @@
           typedef typename boost::result_of<typename decay<F>::type()>::type R;
           typedef packaged_task<R> packaged_task_type;
 
- typedef detail::async_func<typename decay<F>::type> BF;
- typedef typename BF::result_type Rp;
 #endif
 
         if (int(policy) & int(launch::async))
@@ -2973,12 +3181,48 @@
           return ::boost::move(ret);
         }
     }
- template <class F>
- BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
- async(BOOST_THREAD_RV_REF(F) f)
- {
- return async(launch(launch::any), boost::forward<F>(f));
- }
+
+ ////////////////////////////////
+ // template <class F, class... ArgTypes>
+ // future<R> async(F&&, ArgTypes&&...);
+ ////////////////////////////////
+
+#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template <class R, class... ArgTypes>
+ BOOST_THREAD_FUTURE<R>
+ async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args)
+ {
+ return async(launch(launch::any), f, boost::forward<ArgTypes>(args)...);
+ }
+#else
+ template <class R>
+ BOOST_THREAD_FUTURE<R>
+ async(R(*f)())
+ {
+ return async(launch(launch::any), f);
+ }
+#endif
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template <class F, class ...ArgTypes>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
+ typename decay<ArgTypes>::type...
+ )>::type>
+ async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args)
+ {
+ return async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...);
+ }
+#else
+ template <class F>
+ BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
+ async(BOOST_THREAD_RV_REF(F) f)
+ {
+ return async(launch(launch::any), boost::forward<F>(f));
+ }
+#endif
 
 
   ////////////////////////////////

Modified: trunk/libs/thread/test/sync/futures/async/async_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/async/async_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/async/async_pass.cpp 2013-02-10 13:14:49 EST (Sun, 10 Feb 2013)
@@ -25,6 +25,7 @@
 //#define BOOST_THREAD_VERSION 3
 #define BOOST_THREAD_VERSION 4
 
+#include <iostream>
 #include <boost/thread/future.hpp>
 #include <boost/thread/thread.hpp>
 #include <boost/thread/detail/memory.hpp>
@@ -56,20 +57,40 @@
 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 <typename OS>
+ friend OS& operator<<(OS& os, MoveOnly const& v)
+ {
+ os << v.value;
+ return os;
+ }
 };
 
+namespace boost {
+BOOST_THREAD_DCL_MOVABLE(MoveOnly)
+}
+
 int f0()
 {
   boost::this_thread::sleep_for(ms(200));
@@ -89,6 +110,19 @@
   boost::this_thread::sleep_for(ms(200));
 }
 
+boost::interprocess::unique_ptr<int, boost::default_delete<int> > f3_0()
+{
+ boost::this_thread::sleep_for(ms(200));
+ boost::interprocess::unique_ptr<int, boost::default_delete<int> > 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<int, boost::default_delete<int> > f3(int i)
 {
   boost::this_thread::sleep_for(ms(200));
@@ -114,7 +148,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__<<"]"<<ex.what() << std::endl;
       BOOST_TEST(false && "exception thrown");
@@ -285,15 +318,10 @@
   {
     try {
     boost::future<void> f = boost::async(f2);
- std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
     boost::this_thread::sleep_for(ms(300));
- std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
     Clock::time_point t0 = Clock::now();
- std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
     f.get();
- std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
     Clock::time_point t1 = Clock::now();
- std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
     BOOST_TEST(t1 - t0 < ms(200));
     std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
     } catch (std::exception& ex) {
@@ -356,8 +384,59 @@
   }
 #endif
 
- // todo fixme
-#if 0 && defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try {
+ boost::future<MoveOnly> 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__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ } catch (...) {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try {
+ boost::future<MoveOnly> 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__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ } catch (...) {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try {
+ boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f3_0);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ 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__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ } catch (...) {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
   std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
   {
     try {
@@ -375,10 +454,44 @@
       BOOST_TEST(false && "exception thrown");
     }
   }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try {
+ boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f3, 3);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ 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__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ } catch (...) {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
 #endif
 
- // todo fixme
-#if 0 && defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try {
+ boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(boost::launch::async, &f4, boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(3)));
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ 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__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ } catch (...) {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
   {
     try {
     boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f4, boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(3)));


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