Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r50664 - in sandbox/interthreads/boost/interthreads: . algorithm
From: vicente.botet_at_[hidden]
Date: 2009-01-18 18:47:15


Author: viboes
Date: 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
New Revision: 50664
URL: http://svn.boost.org/trac/boost/changeset/50664

Log:
interthreads version 0.3
Adding fork_after and act traits

Added:
   sandbox/interthreads/boost/interthreads/act_traits.hpp (contents, props changed)
   sandbox/interthreads/boost/interthreads/fork_after.hpp (contents, props changed)
Text files modified:
   sandbox/interthreads/boost/interthreads/algorithm.hpp | 6 ++-
   sandbox/interthreads/boost/interthreads/algorithm/wait_all.hpp | 3 -
   sandbox/interthreads/boost/interthreads/asynchronous_executor_decorator.hpp | 18 +++++++++++
   sandbox/interthreads/boost/interthreads/basic_threader.hpp | 6 ++-
   sandbox/interthreads/boost/interthreads/fork.hpp | 31 ++++++++------------
   sandbox/interthreads/boost/interthreads/fork_all.hpp | 14 +++++++++
   sandbox/interthreads/boost/interthreads/launcher.hpp | 37 ++++++++++++++++++++++++
   sandbox/interthreads/boost/interthreads/scheduler.hpp | 25 ++++++++++++++--
   sandbox/interthreads/boost/interthreads/threader.hpp | 59 ++++++++++++++++++++++++++++++---------
   sandbox/interthreads/boost/interthreads/wait_for_all.hpp | 14 +++++++++
   10 files changed, 170 insertions(+), 43 deletions(-)

Added: sandbox/interthreads/boost/interthreads/act_traits.hpp
==============================================================================
--- (empty file)
+++ sandbox/interthreads/boost/interthreads/act_traits.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -0,0 +1,60 @@
+#ifndef BOOST_INTERTHREADS_ACT_TRAITS__HPP
+#define BOOST_INTERTHREADS_ACT_TRAITS__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-20009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or
+// copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/interthreads for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/bind.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/futures/future.hpp>
+#include <boost/mpl/bool.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace interthreads {
+
+template <typename ACT>
+struct act_value;
+
+template <typename ACT>
+struct is_movable : mpl::false_{};
+
+template <typename ACT>
+struct has_future_if : mpl::false_{};
+
+template <typename ACT>
+struct has_thread_if : mpl::false_{};
+
+template <typename AE, typename T>
+struct asynchronous_completion_token {
+ typedef typename AE::template handle<T>::type type;
+};
+
+
+template <typename AE>
+struct get_future {
+ template <typename T>
+ shared_future<T>& operator()(typename asynchronous_completion_token<AE,T>::type& act) { return act.get_future(); }
+};
+
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+

Modified: sandbox/interthreads/boost/interthreads/algorithm.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -11,6 +11,8 @@
 #ifndef BOOST_INTERTHREADS_ALGORITHM__HPP
 #define BOOST_INTERTHREADS_ALGORITHM__HPP
 
+#include <boost/interthreads/fork.hpp>
+#include <boost/interthreads/fork_after.hpp>
 #include <boost/interthreads/fork_all.hpp>
 #include <boost/interthreads/wait_for_all.hpp>
 #include <boost/interthreads/wait_for_any.hpp>
@@ -20,8 +22,8 @@
 #include <boost/interthreads/algorithm/join_all.hpp>
 #include <boost/interthreads/algorithm/join_all_until.hpp>
 //#include <boost/interthreads/algorithm/join_all_for.hpp>
-#include <boost/interthreads/algorithm/get_all.hpp>
-#include <boost/interthreads/algorithm/get_all_until.hpp>
+//#include <boost/interthreads/algorithm/get_all.hpp>
+//#include <boost/interthreads/algorithm/get_all_until.hpp>
 //#include <boost/interthreads/algorithm/get_all_for.hpp>
 #include <boost/interthreads/algorithm/wait_all.hpp>
 #include <boost/interthreads/algorithm/wait_all_until.hpp>

Modified: sandbox/interthreads/boost/interthreads/algorithm/wait_all.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm/wait_all.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm/wait_all.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -29,7 +29,6 @@
             typedef void result_type;
             template<typename ACT>
             void operator()(ACT& act) const {
- //std::cout << "wait()" << std::endl;
                 act.wait();
             }
         };
@@ -45,7 +44,7 @@
     template <typename Sequence>
     typename result_of::wait_all<Sequence>::type
     wait_all(Sequence& t) {
- return fusion::for_each(t, fct::wait());
+ fusion::for_each(t, fct::wait());
     }
 
 }

Modified: sandbox/interthreads/boost/interthreads/asynchronous_executor_decorator.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/asynchronous_executor_decorator.hpp (original)
+++ sandbox/interthreads/boost/interthreads/asynchronous_executor_decorator.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -22,6 +22,11 @@
     
     template <typename AE, template <class> class Decorator>
     struct asynchronous_executor_decorator : AE {
+ template <typename T>
+ struct handle {
+ typedef typename AE::template handle<T>::type type;
+ };
+
         template <typename F>
         typename AE::template handle< typename boost::result_of<F()>::type >::type
         fork( F fn ) {
@@ -64,8 +69,19 @@
             
     };
 
- //typedef asynchronous_executor_decorator<threader,thread_decorator> threader_decorator;
     
+ template <typename AE, template <class> class Decorator>
+ struct get_future<asynchronous_executor_decorator<AE, Decorator> > {
+ template <typename T>
+ struct future_type {
+ typedef typename AE::template get_future<AE>::type type;
+ };
+ template <typename T>
+ typename future_type<T>::type&
+ operator()(typename AE::template handle<T>::type & j)
+ { return j.get_future(); }
+ };
+
 }
 }
 

Modified: sandbox/interthreads/boost/interthreads/basic_threader.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/basic_threader.hpp (original)
+++ sandbox/interthreads/boost/interthreads/basic_threader.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -52,11 +52,13 @@
         thread th(f);
 #endif
         return boost::move(th);
- //return thread(boost::detail::thread_move_t<thread>(th));
     }
 };
 
-
+template <>
+struct act_value<thread> {
+ typedef void type;
+};
 }
 }
 

Modified: sandbox/interthreads/boost/interthreads/fork.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/fork.hpp (original)
+++ sandbox/interthreads/boost/interthreads/fork.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -17,6 +17,7 @@
 #include <boost/bind.hpp>
 #include <boost/utility/result_of.hpp>
 #include <boost/futures/future.hpp>
+#include <boost/interthreads/act_traits.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 
@@ -24,10 +25,6 @@
 namespace boost {
 namespace interthreads {
 
-template <typename AE, typename T>
-struct asynchronous_completion_token {
- typedef typename AE::template handle<T>::type type;
-};
 
     
 namespace result_of {
@@ -37,27 +34,19 @@
         typedef typename asynchronous_completion_token<AE, result_type>::type type;
     };
 }
-
-//template <typename AE>
-//struct get_future;
-template <typename AE>
-struct get_future {
- template <typename T>
- shared_future<T>& operator()(typename asynchronous_completion_token<AE,T>::type& act) { return act.get_future(); }
-};
-
-
+
+namespace partial_specialization_workaround {
 template< typename AE, typename F >
-struct fork_aux {
- static typename result_of::fork<AE,F>::type fork(AE& ae, F fn ) {
+struct fork {
+ static typename result_of::fork<AE,F>::type apply(AE& ae, F fn ) {
         return ae.fork(fn);
     }
 };
-
+}
 template< typename AE, typename F >
 typename result_of::fork<AE,F>::type
 fork( AE& ae, F fn ) {
- return fork_aux<AE,F>::fork(ae,fn);
+ return partial_specialization_workaround::fork<AE,F>::apply(ae,fn);
 }
 
 template< typename AE, typename F, typename A1 >
@@ -78,6 +67,12 @@
     return ae.fork( bind( fn, a1, a2, a3 ) );
 }
 
+template< typename AE, typename F, typename A1, typename A2, typename A3, typename A4 >
+typename asynchronous_completion_token<AE, typename boost::result_of<F(A1,A2,A3,A4)>::type >::type
+fork( AE& ae, F fn, A1 a1, A2 a2, A3 a3, A4 a4 ) {
+ return ae.fork( bind( fn, a1, a2, a3, a4 ) );
+}
+
 }
 }
 

Added: sandbox/interthreads/boost/interthreads/fork_after.hpp
==============================================================================
--- (empty file)
+++ sandbox/interthreads/boost/interthreads/fork_after.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -0,0 +1,193 @@
+#ifndef BOOST_INTERTHREADS_FORK_AFTER__HPP
+#define BOOST_INTERTHREADS_FORK_AFTER__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-20009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or
+// copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/interthreads for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/futures/future.hpp>
+#include <boost/interthreads/fork.hpp>
+#include <boost/interthreads/algorithm/wait_all.hpp>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace interthreads {
+
+#define ACT_WRAPPER
+#ifdef ACT_WRAPPER
+
+template <typename ACT>
+struct act_wrapper {
+ act_wrapper() :ptr_(new data()) {}
+ void wait_initialized() {
+ while (!ptr_->inittialized_) {
+ unique_lock<mutex> lk(ptr_->mtx_);
+ ptr_->cv_.wait(lk);
+ }
+ }
+ void wait() {
+ wait_initialized();
+ ptr_->act_.wait();
+ }
+
+ typename act_value<ACT>::type get() {
+ wait_initialized();
+ return ptr_->act_.get();
+ }
+
+ void join() {
+ wait_initialized();
+ ptr_->act_.join();
+ }
+ void set_initialized(ACT& other) {
+ ptr_->act_=boost::move(other);
+ ptr_->inittialized_=true;
+ ptr_->cv_.notify_all();
+ }
+private:
+ struct data {
+ data()
+ : inittialized_(false)
+ {}
+ ACT act_;
+ bool inittialized_;
+ mutex mtx_;
+ condition_variable cv_;
+ };
+ shared_ptr<data> ptr_;
+};
+
+template <typename ACT>
+struct act_value<act_wrapper<ACT> > {
+ typedef typename act_value<ACT>::type type;
+};
+
+template <typename ACT>
+struct is_movable<act_wrapper<ACT> > : is_movable<ACT>{};
+
+template <typename ACT>
+struct has_future_if<act_wrapper<ACT> > : has_future_if<ACT> {};
+
+template <typename ACT>
+struct has_thread_if<act_wrapper<ACT> > : has_thread_if<ACT>{};
+
+
+namespace result_of {
+ template <typename AE,typename F>
+ struct fork_after {
+ typedef typename boost::result_of<F()>::type result_type;
+ typedef typename asynchronous_completion_token<AE, result_type>::type act_type;
+ typedef act_wrapper<act_type> type;
+ };
+}
+
+#else
+namespace result_of {
+ template <typename AE,typename F>
+ struct fork_after {
+ typedef void type;
+ };
+}
+#endif
+template <typename AE, typename F, typename D>
+struct call_f_after {
+ typedef void result_type;
+#ifndef ACT_WRAPPER
+ void operator()(AE& ae, F fn, D& d, typename AE:: template handle<typename boost::result_of<F()>::type>::type& h) {
+ //d.wait();
+ boost::interthreads::wait_all(d);
+ typename AE:: template handle<typename boost::result_of<F()>::type>::type tmp = fork(ae, fn);
+ //h = boost::move(tmp);
+ h = tmp;
+
+ }
+#else
+ void operator()(AE& ae, F fn, D& d, act_wrapper<typename AE:: template handle<typename boost::result_of<F()>::type>::type>& h) {
+ //d.wait();
+ boost::interthreads::wait_all(d);
+ typename AE:: template handle<typename boost::result_of<F()>::type>::type tmp = fork(ae, fn);
+ //h = boost::move(tmp);
+ h.set_initialized(tmp);
+ }
+#endif
+};
+
+namespace partial_specialization_workaround {
+template< typename AE, typename F, typename D >
+struct fork_after {
+#ifndef ACT_WRAPPER
+ static void
+ apply(AE& ae, F fn, D& d, typename AE:: template handle<typename boost::result_of<F()>::type>::type& h ) {
+ call_f_after<AE,F,D> f;
+ boost::interthreads::fork(ae, boost::bind(f, boost::ref(ae), fn, boost::ref(d), boost::ref(h)));
+ }
+#else
+ static typename result_of::fork_after<AE,F>::type
+ apply(AE& ae, F fn, D& d) {
+ act_wrapper<typename AE:: template handle<typename boost::result_of<F()>::type>::type> h;
+ call_f_after<AE,F,D> f;
+ boost::interthreads::fork(ae, boost::bind(f, boost::ref(ae), fn, boost::ref(d), boost::ref(h)));
+ return h;
+ }
+#endif
+};
+}
+template< typename AE, typename F, typename D>
+#ifndef ACT_WRAPPER
+void
+fork_after( AE& ae, F fn, D& d, typename AE:: template handle<typename boost::result_of<F()>::type>::type& h) {
+ return partial_specialization_workaround::fork_after<AE,F,D>::apply(ae,fn, d, h);
+}
+#else
+typename result_of::fork_after<AE,F>::type
+fork_after( AE& ae, F fn, D& d) {
+ return partial_specialization_workaround::fork_after<AE,F,D>::apply(ae,fn, d);
+}
+#endif
+
+#if 0
+template< typename AE, typename F, typename A1 >
+typename asynchronous_completion_token<AE, typename boost::result_of<F(A1)>::type >::type
+fork( AE& ae, F fn, A1 a1 ) {
+ return ae.fork( bind( fn, a1 ) );
+}
+
+template< typename AE, typename F, typename A1, typename A2 >
+typename asynchronous_completion_token<AE, typename boost::result_of<F(A1,A2)>::type >::type
+fork( AE& ae, F fn, A1 a1, A2 a2 ) {
+ return ae.fork( bind( fn, a1, a2 ) );
+}
+
+template< typename AE, typename F, typename A1, typename A2, typename A3 >
+typename asynchronous_completion_token<AE, typename boost::result_of<F(A1,A2,A3)>::type >::type
+fork( AE& ae, F fn, A1 a1, A2 a2, A3 a3 ) {
+ return ae.fork( bind( fn, a1, a2, a3 ) );
+}
+#endif
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+

Modified: sandbox/interthreads/boost/interthreads/fork_all.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/fork_all.hpp (original)
+++ sandbox/interthreads/boost/interthreads/fork_all.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -29,6 +29,12 @@
 namespace result_of {
     template <typename AE, typename T>
     struct fork_all;
+ template <typename AE, typename F1>
+ struct fork_all<AE, fusion::tuple<F1> > {
+ typedef fusion::tuple<
+ typename result_of::fork<AE,F1>::type
+ > type;
+ };
     template <typename AE, typename F1, typename F2>
     struct fork_all<AE, fusion::tuple<F1,F2> > {
         typedef fusion::tuple<
@@ -48,6 +54,14 @@
 }
 
 
+template< typename AE, typename F1>
+typename result_of::fork_all<AE, fusion::tuple<F1> >::type
+fork_all( AE& ae, F1 f1 ) {
+ typedef typename result_of::fork_all<AE, fusion::tuple<F1> >::type type;
+ typename result_of::fork<AE, F1>::type j1 =ae.fork(f1);
+ return type(j1);
+}
+
 template< typename AE, typename F1, typename F2>
 typename result_of::fork_all<AE, fusion::tuple<F1,F2> >::type
 fork_all( AE& ae, F1 f1, F2 f2 ) {

Modified: sandbox/interthreads/boost/interthreads/launcher.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/launcher.hpp (original)
+++ sandbox/interthreads/boost/interthreads/launcher.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -14,7 +14,6 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 
-//#include <boost/interthreads/detail/config.hpp>
 #include <boost/thread/detail/move.hpp>
 #include <boost/thread/thread.hpp>
 #include <boost/futures/future.hpp>
@@ -95,16 +94,52 @@
 template <>
 struct get_future<launcher> {
     template <typename T>
+ struct future_type {
+ typedef unique_future<T> type;
+ };
+ template <typename T>
     unique_future<T>& operator()(unique_future<T>& f) { return f; }
 };
 
 template <>
 struct get_future<shared_launcher> {
     template <typename T>
+ struct future_type {
+ typedef shared_future<T> type;
+ };
+ template <typename T>
     shared_future<T>& operator()(shared_future<T>& f) { return f; }
 };
 
 
+template <typename ResultType>
+struct act_value<unique_future<ResultType> > {
+ typedef ResultType type;
+};
+
+template <typename R>
+struct is_movable<unique_future<R> > : mpl::true_{};
+
+template <typename R>
+struct has_future_if<unique_future<R> > : mpl::true_{};
+
+template <typename R>
+struct has_thread_if<unique_future<R> > : mpl::false_{};
+
+
+template <typename ResultType>
+struct act_value<shared_future<ResultType> > {
+ typedef ResultType type;
+};
+
+template <typename R>
+struct is_movable<shared_future<R> > : mpl::true_{};
+
+template <typename R>
+struct has_future_if<shared_future<R> > : mpl::true_{};
+
+template <typename R>
+struct has_thread_if<shared_future<R> > : mpl::false_{};
 }
 }
 

Modified: sandbox/interthreads/boost/interthreads/scheduler.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/scheduler.hpp (original)
+++ sandbox/interthreads/boost/interthreads/scheduler.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -57,6 +57,10 @@
 template <typename Channel>
 struct get_future<scheduler<Channel> > {
     template <typename T>
+ struct future_type {
+ typedef shared_future<T> type;
+ };
+ template <typename T>
     shared_future<T>& operator()(tp::task<T>& act) { return act.get_future(); }
 };
 
@@ -68,20 +72,35 @@
 };
 
 
+namespace partial_specialization_workaround {
 template< typename Channel, typename F >
-struct fork_aux<boost::tp::pool<Channel>,F> {
+struct fork<boost::tp::pool<Channel>,F> {
     typename result_of::fork<boost::tp::pool<Channel>, F>::type
- fork( boost::tp::pool<Channel>& ae, F fn ) {
+ apply( boost::tp::pool<Channel>& ae, F fn ) {
         return ae.submit(fn);
     }
 };
-
+}
 template <typename C>
 struct get_future<tp::pool<C> > {
     template <typename T>
     shared_future<T>& operator()(tp::task<T>& act) { return act.get_future(); }
 };
 
+template <typename ResultType>
+struct act_value<tp::task<ResultType> > {
+ typedef ResultType type;
+};
+
+template <typename R>
+struct is_movable<tp::task<R> > : mpl::false_{};
+
+template <typename R>
+struct has_future_if<tp::task<R> > : mpl::true_{};
+
+template <typename R>
+struct has_thread_if<tp::task<R> > : mpl::false_{};
+
 }
 }
 

Modified: sandbox/interthreads/boost/interthreads/threader.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/threader.hpp (original)
+++ sandbox/interthreads/boost/interthreads/threader.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -35,6 +35,7 @@
 template <typename ResultType>
 class unique_joiner;
     
+
 template <typename ResultType>
 class unique_joiner {
 public:
@@ -74,7 +75,7 @@
 
     unique_joiner(unique_joiner& other);
     this_type& operator=(unique_joiner& other);
-
+//protected:
 public:
     friend class unique_threader;
     template <typename Nullary>
@@ -135,12 +136,10 @@
     
     void join() {
         data_->th_.join();
-// wait();
     }
 
     bool join_until(const system_time& abs_time) {
                 return data_->th_.timed_join(abs_time);
-// return wait_until(abs_time);
     }
 
     template<typename TimeDuration>
@@ -148,15 +147,14 @@
     {
         return join_until(get_system_time()+rel_time);
     }
-
+#if 0
     result_type get() const {
- //data_->th_.join();
         return const_cast<unique_future< result_type >*>(&(data_->fut_))->get();
     }
    
     result_type operator()() const { return get(); }
+#endif
     result_type get() {
- //data_->th_.join();
         return data_->fut_.get();
     }
     result_type operator()() { return get(); }
@@ -204,7 +202,20 @@
         return data_->fut_;
     }
 };
+template <typename ResultType>
+struct act_value<unique_joiner<ResultType> > {
+ typedef ResultType type;
+};
 
+template <typename R>
+struct is_movable<unique_joiner<R> > : mpl::true_{};
+
+template <typename R>
+struct has_future_if<unique_joiner<R> > : mpl::true_{};
+
+template <typename R>
+struct has_thread_if<unique_joiner<R> > : mpl::true_{};
+
 class unique_threader {
 #ifdef BOOST_THREAD_HAS_THREAD_ATTR
 private:
@@ -240,6 +251,10 @@
 template <>
 struct get_future<unique_threader> {
     template <typename T>
+ struct future_type {
+ typedef unique_future<T> type;
+ };
+ template <typename T>
     unique_future<T>& operator()(unique_joiner<T>& j) { return j.get_future(); }
 };
 
@@ -296,21 +311,22 @@
     shared_joiner(Nullary f)
     : data_(new this_impl_type(f))
 #endif
- {}
+ {
+ }
 
 public:
+ shared_joiner() : data_() {};
     shared_joiner(const shared_joiner& other) : data_(other.data_){
     }
     this_type& operator=(const shared_joiner& other) {
         data_=other.data_;
- other.data_.reset(new this_impl_type());
         return *this;
     }
 
     // move support
 #ifdef BOOST_HAS_RVALUE_REFS
- shared_joiner(this_type&& other) {
- data_.swap(other.data_);
+ shared_joiner(this_type&& other): data_(other.data_) {
+ other.data_.reset(new this_impl_type());
     }
     shared_joiner& operator=(shared_joiner&& other) {
         data_=other.data_;
@@ -353,12 +369,10 @@
     
     void join() {
         data_->th_.join();
-// wait();
     }
 
     bool join_until(const system_time& abs_time) {
                 return data_->th_.timed_join(abs_time);
-// return wait_until(abs_time);
     }
 
     template<typename TimeDuration>
@@ -367,12 +381,10 @@
         return join_until(get_system_time()+rel_time);
     }
     result_type get() {
- //data_->th_.join();
         return data_->fut_.get();
     }
     result_type operator()() { return get(); }
     result_type get() const {
- //data_->th_.join();
         return const_cast<shared_future< result_type >*>(&(data_->fut_))->get();
     }
    
@@ -422,6 +434,21 @@
     }
 };
 
+template <typename R>
+struct act_value<shared_joiner<R> > {
+ typedef R type;
+};
+
+template <typename R>
+struct is_movable<shared_joiner<R> > : mpl::true_{};
+
+template <typename R>
+struct has_future_if<shared_joiner<R> > : mpl::true_{};
+
+template <typename R>
+struct has_thread_if<shared_joiner<R> > : mpl::true_{};
+
+
 class shared_threader {
 #ifdef BOOST_THREAD_HAS_THREAD_ATTR
 private:
@@ -456,6 +483,10 @@
 template <>
 struct get_future<shared_threader> {
     template <typename T>
+ struct future_type {
+ typedef shared_future<T> type;
+ };
+ template <typename T>
     shared_future<T>& operator()(shared_joiner<T>& j) { return j.get_future(); }
 };
 

Modified: sandbox/interthreads/boost/interthreads/wait_for_all.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/wait_for_all.hpp (original)
+++ sandbox/interthreads/boost/interthreads/wait_for_all.hpp 2009-01-18 18:47:14 EST (Sun, 18 Jan 2009)
@@ -29,6 +29,12 @@
 namespace result_of {
     template <typename L, typename T>
     struct wait_for_all;
+ template <typename L, typename F1>
+ struct wait_for_all<L,fusion::tuple<F1> > {
+ typedef fusion::tuple<
+ typename boost::result_of<F1()>::type
+ > type;
+ };
     template <typename L, typename F1, typename F2>
     struct wait_for_all<L,fusion::tuple<F1,F2> > {
         typedef fusion::tuple<
@@ -47,6 +53,14 @@
     
 }
 
+template< typename AE, typename F1>
+typename result_of::wait_for_all<AE, fusion::tuple<F1> >::type
+wait_for_all( AE& ae, F1 f1 ) {
+ typename result_of::fork_all<AE, fusion::tuple<F1> >::type handles(fork_all(ae, f1));
+ typename result_of::wait_for_all<AE, fusion::tuple<F1> >::type values;
+ set_all(handles,values);
+ return values;
+}
 
 template< typename AE, typename F1, typename F2>
 typename result_of::wait_for_all<AE, fusion::tuple<F1,F2> >::type


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