$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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