$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r83811 - in branches/release: boost/thread boost/thread/detail libs/thread libs/thread/example libs/thread/test libs/thread/test/sync/futures/async libs/thread/test/sync/futures/future libs/thread/test/sync/futures/shared_future libs/thread/test/threads/thread/constr
From: vicente.botet_at_[hidden]
Date: 2013-04-08 13:23:03
Author: viboes
Date: 2013-04-08 13:23:02 EDT (Mon, 08 Apr 2013)
New Revision: 83811
URL: http://svn.boost.org/trac/boost/changeset/83811
Log:
Thread: merge from trunk 1.54: Added lambda tests, refactored future::then, added tests for future::wait...
Added:
   branches/release/libs/thread/example/lambda_future.cpp
      - copied unchanged from r83800, /trunk/libs/thread/example/lambda_future.cpp
   branches/release/libs/thread/test/sync/futures/future/wait_for_pass.cpp
      - copied unchanged from r83800, /trunk/libs/thread/test/sync/futures/future/wait_for_pass.cpp
   branches/release/libs/thread/test/sync/futures/future/wait_pass.cpp
      - copied unchanged from r83800, /trunk/libs/thread/test/sync/futures/future/wait_pass.cpp
   branches/release/libs/thread/test/sync/futures/future/wait_until_pass.cpp
      - copied unchanged from r83800, /trunk/libs/thread/test/sync/futures/future/wait_until_pass.cpp
   branches/release/libs/thread/test/sync/futures/shared_future/wait_for_pass.cpp
      - copied unchanged from r83800, /trunk/libs/thread/test/sync/futures/shared_future/wait_for_pass.cpp
   branches/release/libs/thread/test/sync/futures/shared_future/wait_pass.cpp
      - copied unchanged from r83800, /trunk/libs/thread/test/sync/futures/shared_future/wait_pass.cpp
   branches/release/libs/thread/test/sync/futures/shared_future/wait_until_pass.cpp
      - copied unchanged from r83800, /trunk/libs/thread/test/sync/futures/shared_future/wait_until_pass.cpp
   branches/release/libs/thread/test/threads/thread/constr/lambda_pass.cpp
      - copied unchanged from r83800, /trunk/libs/thread/test/threads/thread/constr/lambda_pass.cpp
Properties modified: 
   branches/release/boost/thread/   (props changed)
   branches/release/libs/thread/   (props changed)
Text files modified: 
   branches/release/boost/thread/detail/config.hpp                     |     7                                         
   branches/release/boost/thread/future.hpp                            |  1040 ++++++++++++++++++++++++++------------- 
   branches/release/libs/thread/example/future_then.cpp                |    10                                         
   branches/release/libs/thread/example/tennis.cpp                     |     9                                         
   branches/release/libs/thread/test/Jamfile.v2                        |    42 +                                       
   branches/release/libs/thread/test/sync/futures/async/async_pass.cpp |    12                                         
   branches/release/libs/thread/test/sync/futures/future/get_pass.cpp  |    28                                         
   branches/release/libs/thread/test/sync/futures/future/then_pass.cpp |    84 +-                                      
   8 files changed, 801 insertions(+), 431 deletions(-)
Modified: branches/release/boost/thread/detail/config.hpp
==============================================================================
--- branches/release/boost/thread/detail/config.hpp	(original)
+++ branches/release/boost/thread/detail/config.hpp	2013-04-08 13:23:02 EDT (Mon, 08 Apr 2013)
@@ -158,7 +158,7 @@
 // fixme BOOST_THREAD_PROVIDES_ONCE_CXX11 doesn't works when thread.cpp is compiled BOOST_THREAD_VERSION 3
 #if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 \
  && ! defined BOOST_THREAD_PROVIDES_ONCE_CXX11
-#define BOOST_THREAD_PROVIDES_ONCE_CXX11
+#define BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11
 #endif
 
 // THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
@@ -371,8 +371,9 @@
 #elif defined(BOOST_THREAD_USE_LIB)   //Use lib
 #else //Use default
 #   if defined(BOOST_THREAD_PLATFORM_WIN32)
-#       if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)
-            //For compilers supporting auto-tss cleanup
+#       if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) \
+      || defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32)
+      //For compilers supporting auto-tss cleanup
             //with Boost.Threads lib, use Boost.Threads lib
 #           define BOOST_THREAD_USE_LIB
 #       else
Modified: branches/release/boost/thread/future.hpp
==============================================================================
--- branches/release/boost/thread/future.hpp	(original)
+++ branches/release/boost/thread/future.hpp	2013-04-08 13:23:02 EDT (Mon, 08 Apr 2013)
@@ -1,5 +1,5 @@
 //  (C) Copyright 2008-10 Anthony Williams
-//  (C) Copyright 2011-2012 Vicente J. Botet Escriba
+//  (C) Copyright 2011-2013 Vicente J. Botet Escriba
 //
 //  Distributed under the Boost Software License, Version 1.0. (See
 //  accompanying file LICENSE_1_0.txt or copy at
@@ -67,41 +67,41 @@
 namespace boost
 {
 
-    //enum class launch
-    BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
-    {
-        none = 0,
-        async = 1,
-        deferred = 2,
-        any = async | deferred
-    }
-    BOOST_SCOPED_ENUM_DECLARE_END(launch)
+  //enum class launch
+  BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
+  {
+      none = 0,
+      async = 1,
+      deferred = 2,
+      any = async | deferred
+  }
+  BOOST_SCOPED_ENUM_DECLARE_END(launch)
 
-    //enum class future_status
-    BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
-    {
-        ready,
-        timeout,
-        deferred
-    }
-    BOOST_SCOPED_ENUM_DECLARE_END(future_status)
+  //enum class future_status
+  BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
+  {
+      ready,
+      timeout,
+      deferred
+  }
+  BOOST_SCOPED_ENUM_DECLARE_END(future_status)
 
-    class BOOST_SYMBOL_VISIBLE future_error
-        : public std::logic_error
-    {
-        system::error_code ec_;
-    public:
-        future_error(system::error_code ec)
-        : logic_error(ec.message()),
-          ec_(ec)
-        {
-        }
+  class BOOST_SYMBOL_VISIBLE future_error
+      : public std::logic_error
+  {
+      system::error_code ec_;
+  public:
+      future_error(system::error_code ec)
+      : logic_error(ec.message()),
+        ec_(ec)
+      {
+      }
 
-        const system::error_code& code() const BOOST_NOEXCEPT
-        {
-          return ec_;
-        }
-    };
+      const system::error_code& code() const BOOST_NOEXCEPT
+      {
+        return ec_;
+      }
+  };
 
     class BOOST_SYMBOL_VISIBLE future_uninitialized:
         public future_error
@@ -145,23 +145,23 @@
         {}
     };
 
-    class BOOST_SYMBOL_VISIBLE task_moved:
-        public future_error
-    {
-    public:
-        task_moved():
-          future_error(system::make_error_code(future_errc::no_state))
-        {}
-    };
+        class BOOST_SYMBOL_VISIBLE task_moved:
+            public future_error
+        {
+        public:
+            task_moved():
+              future_error(system::make_error_code(future_errc::no_state))
+            {}
+        };
 
-    class promise_moved:
-        public future_error
-    {
-    public:
-          promise_moved():
-          future_error(system::make_error_code(future_errc::no_state))
-        {}
-    };
+            class promise_moved:
+                public future_error
+            {
+            public:
+                  promise_moved():
+                  future_error(system::make_error_code(future_errc::no_state))
+                {}
+            };
 
     namespace future_state
     {
@@ -171,20 +171,10 @@
     namespace detail
     {
 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
-        struct future_continuation_base
-        {
-          future_continuation_base() {}
-          virtual ~future_continuation_base() {}
-
-          virtual void do_continuation(boost::unique_lock<boost::mutex>& ) {};
-        private:
-          future_continuation_base(future_continuation_base const&);
-          future_continuation_base& operator=(future_continuation_base const&);
-        };
-
-        template <typename F, typename R, typename C>
-        struct future_continuation;
-
+      template<typename F, typename Rp, typename Fp>
+      struct future_deferred_continuation;
+      template<typename F, typename Rp, typename Fp>
+      struct future_async_continuation;
 #endif
 
         struct relocker
@@ -231,18 +221,29 @@
             bool thread_was_interrupted;
 //#endif
 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
-            shared_ptr<future_continuation_base> continuation_ptr;
+            typedef shared_ptr<future_object_base> continuation_ptr_type;
 #else
-            shared_ptr<void> continuation_ptr;
+            typedef shared_ptr<void> continuation_ptr_type;
 #endif
+            continuation_ptr_type continuation_ptr;
+
+
+//#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+            virtual void launch_continuation(boost::unique_lock<boost::mutex>&)
+            {
+            }
+//#endif
             future_object_base():
                 done(false),
                 is_deferred_(false),
                 policy_(launch::none),
                 is_constructed(false)
+
+            // This declaration should be only included conditinally, but are included to maintain the same layout.
 //#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
               , thread_was_interrupted(false)
 //#endif
+            // This declaration should be only included conditinally, but are included to maintain the same layout.
 //#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
                , continuation_ptr()
 //#endif
@@ -282,7 +283,10 @@
             void do_continuation(boost::unique_lock<boost::mutex>& lock)
             {
                 if (continuation_ptr) {
-                  continuation_ptr->do_continuation(lock);
+                  continuation_ptr->launch_continuation(lock);
+                  if (! lock.owns_lock())
+                    lock.lock();
+                  continuation_ptr.reset();
                 }
             }
 #else
@@ -291,9 +295,9 @@
             }
 #endif
 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
-            void set_continuation_ptr(future_continuation_base* continuation, boost::unique_lock<boost::mutex>& lock)
+            void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
             {
-              continuation_ptr.reset(continuation);
+              continuation_ptr= continuation;
               if (done) {
                 do_continuation(lock);
               }
@@ -330,7 +334,7 @@
             void wait_internal(boost::unique_lock<boost::mutex> &lock, bool rethrow=true)
             {
               do_callback(lock);
-              //if (!done) // fixme why this doesn't works?
+              //if (!done) // fixme why this doesn't work?
               {
                 if (is_deferred_)
                 {
@@ -476,7 +480,7 @@
                     );
             }
             bool is_deferred()  const BOOST_NOEXCEPT {
-                return is_deferred_ == true;
+                return is_deferred_;
             }
 
             launch launch_policy() const BOOST_NOEXCEPT
@@ -500,26 +504,27 @@
         template<typename T>
         struct future_traits
         {
-            typedef boost::scoped_ptr<T> storage_type;
-            struct dummy;
+          typedef boost::scoped_ptr<T> storage_type;
+          struct dummy;
 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-            typedef T const& source_reference_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;
+          typedef T const& source_reference_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 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;
-            typedef typename boost::mpl::if_<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(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;
+          typedef typename boost::mpl::if_<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
 #endif
 
+
             typedef const T& shared_future_get_result_type;
 
             static void init(storage_type& storage,source_reference_type t)
@@ -547,8 +552,8 @@
         {
             typedef T* storage_type;
             typedef T& source_reference_type;
-            struct rvalue_source_type
-            {};
+            //struct rvalue_source_type
+            //{};
             typedef T& move_dest_type;
             typedef T& shared_future_get_result_type;
 
@@ -600,13 +605,12 @@
             {}
 
             ~future_object()
-            {
-            }
+            {}
 
             void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
             {
                 future_traits<T>::init(result,result_);
-                mark_finished_internal(lock);
+                this->mark_finished_internal(lock);
             }
 
             void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
@@ -616,38 +620,36 @@
 #else
                 future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
 #endif
-                mark_finished_internal(lock);
+                this->mark_finished_internal(lock);
             }
 
             void mark_finished_with_result(source_reference_type result_)
             {
                 boost::unique_lock<boost::mutex> lock(mutex);
-                mark_finished_with_result_internal(result_, lock);
+                this->mark_finished_with_result_internal(result_, lock);
             }
 
             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()
+            virtual move_dest_type get()
             {
                 wait();
-                //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 *result;
             }
 
@@ -666,6 +668,7 @@
             }
 
 
+            //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);
@@ -679,13 +682,13 @@
               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());
@@ -703,7 +706,7 @@
         {
             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&>::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;
 
@@ -885,10 +888,9 @@
               this->wait_internal(lock);
 
               //return static_cast<move_dest_type>(*(this->result));
-              return boost::move<Rp>(*(this->result));
-
+              //return boost::move<Rp>(*(this->result));
+              return boost::move(*(this->result));
           }
-
           static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f)
           {
             try
@@ -912,12 +914,11 @@
         struct future_async_object<void, Fp>: public future_object<void>
         {
           typedef future_object<void> base_type;
-
           boost::thread thr_;
 
         public:
           explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f) :
-           thr_(&future_async_object::run, this, boost::forward<Fp>(f))
+            thr_(&future_async_object::run, this, boost::forward<Fp>(f))
           {
             this->set_async();
           }
@@ -946,6 +947,57 @@
             }
           }
         };
+
+        template<typename Rp, typename Fp>
+        struct future_async_object<Rp&, Fp>: future_object<Rp&>
+        {
+          typedef future_object<Rp&> base_type;
+          typedef typename base_type::move_dest_type move_dest_type;
+
+          boost::thread thr_;
+
+        public:
+          explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f) :
+            thr_(&future_async_object::run, this, boost::forward<Fp>(f))
+          {
+            this->set_async();
+          }
+
+          ~future_async_object()
+          {
+            if (thr_.joinable()) thr_.join();
+          }
+
+          move_dest_type get()
+          {
+              if (thr_.joinable()) thr_.join();
+              // fixme Is the lock needed during the whole scope?
+              //this->wait();
+              boost::unique_lock<boost::mutex> lock(this->mutex);
+              this->wait_internal(lock);
+
+              //return static_cast<move_dest_type>(*(this->result));
+              return boost::move(*(this->result));
+          }
+          static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f)
+          {
+            try
+            {
+              that->mark_finished_with_result(f());
+            }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+            catch(thread_interrupted& )
+            {
+              that->mark_interrupted_finish();
+            }
+#endif
+            catch(...)
+            {
+              that->mark_exceptional_finish();
+            }
+          }
+        };
+
         //////////////////////////
         /// future_deferred_object
         //////////////////////////
@@ -973,6 +1025,30 @@
             }
           }
         };
+        template<typename Rp, typename Fp>
+        struct future_deferred_object<Rp&,Fp>: future_object<Rp&>
+        {
+          typedef future_object<Rp&> base_type;
+          Fp func_;
+
+        public:
+          explicit future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f)
+          : func_(boost::forward<Fp>(f))
+          {
+            this->set_deferred();
+          }
+
+          virtual void execute(boost::unique_lock<boost::mutex>& lck) {
+            try
+            {
+              this->mark_finished_with_result_internal(func_(), lck);
+            }
+            catch (...)
+            {
+              this->mark_exceptional_finish_internal(current_exception(), lck);
+            }
+          }
+        };
 
         template<typename Fp>
         struct future_deferred_object<void,Fp>: future_object<void>
@@ -1376,9 +1452,9 @@
     } // detail
     BOOST_THREAD_DCL_MOVABLE_BEG(R) detail::basic_future<R> BOOST_THREAD_DCL_MOVABLE_END
 
-#if (!defined _MSC_VER || _MSC_VER >= 1400) // _MSC_VER == 1400 on MSVC 2005
     namespace detail
     {
+#if (!defined _MSC_VER || _MSC_VER >= 1400) // _MSC_VER == 1400 on MSVC 2005
         template <class Rp, class Fp>
         BOOST_THREAD_FUTURE<Rp>
         make_future_async_object(BOOST_THREAD_FWD_REF(Fp) f);
@@ -1386,9 +1462,20 @@
         template <class Rp, class Fp>
         BOOST_THREAD_FUTURE<Rp>
         make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f);
-    }
 #endif // #if (!defined _MSC_VER || _MSC_VER >= 1400)
 
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+        template <class F, class Rp, class Fp>
+        BOOST_THREAD_FUTURE<Rp>
+        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>
+        BOOST_THREAD_FUTURE<Rp>
+        make_future_deferred_continuation(boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c);
+#endif
+
+    }
+
     template <typename R>
     class BOOST_THREAD_FUTURE : public detail::basic_future<R>
     {
@@ -1400,7 +1487,9 @@
         friend class promise<R>;
 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
         template <typename, typename, typename>
-        friend struct detail::future_continuation;
+        friend struct detail::future_async_continuation;
+        template <typename, typename, typename>
+        friend struct detail::future_deferred_continuation;
 #endif
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
         template <class> friend class packaged_task; // todo check if this works in windows
@@ -1417,6 +1506,16 @@
         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;
 
         BOOST_THREAD_FUTURE(future_ptr a_future):
@@ -1453,6 +1552,17 @@
             static_cast<base_type*>(this)->swap(other);
         }
 
+        // todo this function must be private and friendship provided to the internal users.
+        void set_async()
+        {
+          this->future_->set_async();
+        }
+        // todo this function must be private and friendship provided to the internal users.
+        void set_deferred()
+        {
+          this->future_->set_deferred();
+        }
+
         // retrieving the value
         move_dest_type get()
         {
@@ -1464,6 +1574,7 @@
             future_ptr fut_=this->future_;
             this->future_.reset();
             return fut_->get();
+
 #else
             return this->future_->get();
 #endif
@@ -1475,18 +1586,18 @@
 //        template<typename F>
 //        auto then(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)(BOOST_THREAD_FUTURE&));
-        template<typename RF>
-        inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&));
-#endif
+//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+//        template<typename RF>
+//        inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(BOOST_THREAD_FUTURE&));
+//        template<typename RF>
+//        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_RV_REF(F) func);
+        then(BOOST_THREAD_FWD_REF(F) func);
         template<typename F>
         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE&)>::type>
-        then(launch policy, BOOST_THREAD_RV_REF(F) func);
+        then(launch policy, BOOST_THREAD_FWD_REF(F) func);
 #endif
     };
 
@@ -1675,11 +1786,7 @@
                 boost::throw_exception(future_already_retrieved());
             }
             future_obtained=true;
-            return
-                //BOOST_THREAD_MAKE_RV_REF(
-                BOOST_THREAD_FUTURE<R>(future_)
-                //)
-                ;
+            return BOOST_THREAD_FUTURE<R>(future_);
         }
 
         void set_value(typename detail::future_traits<R>::source_reference_type r)
@@ -1847,7 +1954,6 @@
             }
             future_obtained=true;
             return BOOST_THREAD_FUTURE<R&>(future_);
-            //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<R&>(future_));
         }
 
         void set_value(R& r)
@@ -1993,9 +2099,6 @@
             }
             future_obtained=true;
             return BOOST_THREAD_FUTURE<void>(future_);
-            //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<void>(future_));
-            //BOOST_THREAD_FUTURE<void> res;
-            //return boost::move(res);
         }
 
         void set_value()
@@ -2111,7 +2214,6 @@
 #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)
@@ -2227,8 +2329,7 @@
 #else
                   this->mark_finished_with_result(f());
 #endif
-
-                }
+                  }
 #endif
 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
                 catch(thread_interrupted& )
@@ -2332,7 +2433,6 @@
             }
         };
 
-
 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
 
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
@@ -2372,9 +2472,8 @@
                 {
                     try
                     {
-                      //this->set_value_at_thread_exit(f());
-                      R r((f()));
-                      this->set_value_at_thread_exit(boost::move(r));
+                        R r((f()));
+                        this->set_value_at_thread_exit(boost::move(r));
                     }
 #endif
 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -2402,7 +2501,6 @@
                 {
                     try
                     {
-                        //this->set_value_at_thread_exit(f());
                         R res((f()));
                         this->mark_finished_with_result(boost::move(res));
                     }
@@ -2500,7 +2598,6 @@
                 }
             };
 #endif
-
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
         template<typename F, typename ...ArgTypes>
@@ -2945,7 +3042,6 @@
             {
                 future_obtained=true;
                 return BOOST_THREAD_FUTURE<R>(task);
-                //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<R>(task));
             }
             else
             {
@@ -3084,6 +3180,7 @@
               packaged_task_type pt( f );
 
               BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
+              ret.set_async();
 #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
@@ -3096,13 +3193,21 @@
               packaged_task_type pt( f );
 
               BOOST_THREAD_FUTURE<R> ret = pt.get_future();
+              ret.set_deferred();
               return ::boost::move(ret);
             } else {
+              //BOOST_THREAD_LOG << "ERROR async "<< int(policy) << BOOST_THREAD_END_LOG;
               BOOST_THREAD_FUTURE<R> ret;
               return ::boost::move(ret);
             }
         }
 
+//        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
@@ -3155,6 +3260,7 @@
           packaged_task_type pt( boost::forward<F>(f) );
 
           BOOST_THREAD_FUTURE<R> ret = pt.get_future();
+          ret.set_async();
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
           boost::thread( boost::move(pt), boost::forward<ArgTypes>(args)... ).detach(); // todo forward
 #else
@@ -3183,56 +3289,57 @@
 #endif
 
         } else {
+          //BOOST_THREAD_LOG << "ERROR async "<< int(policy) << BOOST_THREAD_END_LOG;
           BOOST_THREAD_FUTURE<R> ret;
           return ::boost::move(ret);
         }
     }
 
-    ////////////////////////////////
-    // template <class F, class... ArgTypes>
-    // future<R> async(F&&, ArgTypes&&...);
-    ////////////////////////////////
+        ////////////////////////////////
+        // template <class F, class... ArgTypes>
+        // future<R> async(F&&, ArgTypes&&...);
+        ////////////////////////////////
 
-#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+    #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 BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
-        }
-#else
-        template <class R>
-        BOOST_THREAD_FUTURE<R>
-        async(R(*f)())
-        {
-          return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
-        }
-#endif
-#endif
+    #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 BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
+            }
+    #else
+            template <class R>
+            BOOST_THREAD_FUTURE<R>
+            async(R(*f)())
+            {
+              return BOOST_THREAD_MAKE_RV_REF(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 BOOST_THREAD_MAKE_RV_REF(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 BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
-        }
+    #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 BOOST_THREAD_MAKE_RV_REF(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 BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
+    }
 #endif
 
 
   ////////////////////////////////
-  // make_future
+  // make_future deprecated
   ////////////////////////////////
   template <typename T>
   BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value)
@@ -3300,6 +3407,7 @@
       return BOOST_THREAD_MAKE_RV_REF(p.get_future());
   }
 #endif
+
   ////////////////////////////////
   // make_shared_future deprecated
   ////////////////////////////////
@@ -3350,116 +3458,352 @@
     p.set_exception(ex);
     return p.get_future().share();
   }
+
   ////////////////////////////////
-  // detail::future_continuation
+  // detail::future_async_continuation
   ////////////////////////////////
 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
   namespace detail
   {
-      template <typename F, typename R, typename C>
-      struct future_continuation : future_continuation_base
+
+    /////////////////////////
+    /// future_async_continuation
+    /////////////////////////
+
+    template<typename F, typename Rp, typename Fp>
+    struct future_async_continuation: future_object<Rp>
+    {
+      typedef future_object<Rp> base_type;
+      typedef typename base_type::move_dest_type move_dest_type;
+      typedef weak_ptr<future_object_base> parent_ptr_type;
+
+      F parent;
+      Fp continuation;
+      boost::thread thr_;
+
+    public:
+      explicit future_async_continuation(
+          F& f, BOOST_THREAD_FWD_REF(Fp) c
+          ) :
+      parent(f.future_),
+      //continuation(boost::move(c)),
+      continuation(c),
+      thr_()
+      {
+        this->set_async();
+      }
+
+      ~future_async_continuation()
+      {
+        if (thr_.get_id()==thread::id())
+        {
+          //BOOST_THREAD_LOG << "ERRORRRRRRRRR ~future_async_continuation " << this << " " << thr_.get_id() << BOOST_THREAD_END_LOG;
+          return;
+        }
+        if (thr_.joinable()) {
+          thr_.join();
+        }
+      }
+
+      void launch_continuation(boost::unique_lock<boost::mutex>& lock)
+      {
+        lock.unlock();
+        thr_ = thread(&future_async_continuation::run, this);
+      }
+
+      move_dest_type get()
+      {
+          if (thr_.joinable()) thr_.join();
+          // fixme Is the lock needed during the whole scope?
+          //this->wait();
+          boost::unique_lock<boost::mutex> lock(this->mutex);
+          this->wait_internal(lock);
+
+          // fixme use boost::move
+          return static_cast<move_dest_type>(*(this->result));
+      }
+      static void run(future_async_continuation* that)
+      {
+        try
+        {
+          that->mark_finished_with_result(that->continuation(that->parent));
+        }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+        catch(thread_interrupted& )
+        {
+          that->mark_interrupted_finish();
+        }
+#endif
+        catch(...)
+        {
+          that->mark_exceptional_finish();
+        }
+      }
+    };
+
+    template<typename F, typename Fp>
+    struct future_async_continuation<F, void, Fp>: public future_object<void>
+    {
+      typedef future_object<void> base_type;
+      F& parent;
+      Fp continuation;
+      boost::thread thr_;
+
+    public:
+      explicit future_async_continuation(
+          F& f, BOOST_THREAD_FWD_REF(Fp) c
+          ) :
+      parent(f),
+      continuation(boost::move(c)),
+      thr_()
+      {
+        this->set_async();
+      }
+
+      ~future_async_continuation()
+      {
+        if (thr_.get_id()==thread::id())
+        {
+          return;
+        }
+        if (thr_.joinable()) thr_.join();
+      }
+
+      void launch_continuation(boost::unique_lock<boost::mutex>& lk)
       {
-        F& parent;
-        C continuation;
-        launch policy_;
-        promise<R> next;
+        lk.unlock();
+        thr_ = thread(&future_async_continuation::run, this);
+      }
 
-        future_continuation(F& f, BOOST_THREAD_FWD_REF(C) c) :
+      static void run(future_async_continuation* that)
+      {
+        try
+        {
+          that->continuation(that->parent);
+          that->mark_finished_with_result();
+        }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+        catch(thread_interrupted& )
+        {
+          that->mark_interrupted_finish();
+        }
+#endif
+        catch(...)
+        {
+          that->mark_exceptional_finish();
+        }
+      }
+    };
+
+
+    //////////////////////////
+    /// future_deferred_continuation
+    //////////////////////////
+    template<typename F, typename Rp, typename Fp>
+    struct future_deferred_continuation: future_object<Rp>
+    {
+      typedef future_object<Rp> base_type;
+      F& parent;
+      Fp continuation;
+
+    public:
+      explicit future_deferred_continuation(
+          F& f, BOOST_THREAD_FWD_REF(Fp) c
+          ) :
           parent(f),
-          continuation(boost::forward<C>(c)),
-          policy_(f.launch_policy()),
-          next()
-        {}
-        future_continuation(F& f, BOOST_THREAD_FWD_REF(C) c, launch policy) :
+          //continuation(boost::move(c))
+          continuation(c)
+      {
+        this->set_deferred();
+      }
+
+      virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk)
+      {
+        execute(lk);
+      }
+
+      virtual void execute(boost::unique_lock<boost::mutex>& lck) {
+        try
+        {
+          this->mark_finished_with_result_internal(continuation(parent), lck);
+        }
+        catch (...)
+        {
+          this->mark_exceptional_finish_internal(current_exception(), lck);
+        }
+      }
+    };
+
+    template<typename F, typename Fp>
+    struct future_deferred_continuation<F,void,Fp>: future_object<void>
+    {
+      typedef future_object<void> base_type;
+      F& parent;
+      Fp continuation;
+
+    public:
+      explicit future_deferred_continuation(
+          F& f, BOOST_THREAD_FWD_REF(Fp) c
+          ):
           parent(f),
-          continuation(boost::forward<C>(c)),
-          policy_(policy),
-          next()
-        {}
-        ~future_continuation()
-        {}
+          continuation(boost::move(c))
+      {
+        this->set_deferred();
+      }
 
-        void do_continuation(boost::unique_lock<boost::mutex>& lk)
+      virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk)
+      {
+        execute(lk);
+      }
+      virtual void execute(boost::unique_lock<boost::mutex>& lck) {
+        try
         {
-          try
-          {
-            lk.unlock();
-            // fixme what to do depending on inherits_launch_policy_ and policy_?
+          continuation(parent);
+          this->mark_finished_with_result_internal(lck);
+        }
+        catch (...)
+        {
+          this->mark_exceptional_finish_internal(current_exception(), lck);
+        }
+      }
+    };
+
+    ////////////////////////////////
+    // make_future_deferred_continuation
+    ////////////////////////////////
+    template<typename F, typename Rp, typename Fp>
+    BOOST_THREAD_FUTURE<Rp>
+    make_future_deferred_continuation(
+        boost::unique_lock<boost::mutex> &lock,
+        F& f, BOOST_THREAD_FWD_REF(Fp) c
+        )
+    {
+      shared_ptr<future_deferred_continuation<F, Rp, Fp> >
+          h(new future_deferred_continuation<F, Rp, Fp>(f, boost::forward<Fp>(c)));
+      f.future_->set_continuation_ptr(h, lock);
+      return BOOST_THREAD_FUTURE<Rp>(h);
+    }
+
+    ////////////////////////////////
+    // make_future_async_continuation
+    ////////////////////////////////
+    template<typename F, typename Rp, typename Fp>
+    BOOST_THREAD_FUTURE<Rp>
+    make_future_async_continuation(
+        boost::unique_lock<boost::mutex> &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c
+        )
+    {
+      shared_ptr<future_async_continuation<F,Rp, Fp> >
+          h(new future_async_continuation<F,Rp, Fp>(f, boost::forward<Fp>(c)));
+      f.future_->set_continuation_ptr(h, lock);
+
+      return BOOST_THREAD_FUTURE<Rp>(h);
+    }
+
+//      template <typename F, typename R, typename C>
+//      struct future_continuation : future_object<R>
+//      {
+//        F& parent;
+//        C continuation;
+//        launch policy_;
+//
+//        future_continuation(boost::unique_lock<boost::mutex>& lk, F& f, BOOST_THREAD_FWD_REF(C) c) :
+//          parent(f),
+//          continuation(boost::forward<C>(c)),
+//          policy_(f.launch_policy())
+//        {
+//          init_continuation(lk);
+//        }
+//        future_continuation(boost::unique_lock<boost::mutex>& lk, F& f, BOOST_THREAD_FWD_REF(C) c, launch policy) :
+//          parent(f),
+//          continuation(boost::forward<C>(c)),
+//          policy_(policy)
+//        {
+//          init_continuation(lk);
+//        }
+//        ~future_continuation()
+//        {}
+//
+//        void init_continuation(boost::unique_lock<boost::mutex>& lk)
+//        {
+//          try
+//          {
+//            lk.unlock();
+//            // fixme what to do depending on inherits_launch_policy_ and policy_?
 //            if (int(policy_) & int(launch::deferred))
-            {
-              R val = continuation(parent);
-              next.set_value(boost::move(val));
-            }
+//            {
+//              R val = continuation(parent);
+//              next.set_value(boost::move(val));
+//            }
 //            else
 //            {
 //              BOOST_THREAD_FUTURE<R> f = async(policy_, continuation, boost::ref(parent));
 //              R val = f.get();
 //              next.set_value(boost::move(val));
 //            }
-          }
-          catch (...)
-          {
-            next.set_exception(boost::current_exception());
-          }
-        }
-      private:
-
-        future_continuation(future_continuation const&);
-        future_continuation& operator=(future_continuation const&);
-      };
-#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
-      template <typename F, typename R, typename CR>
-      struct future_continuation<F,R,CR(*)(F&)> : future_continuation_base
-      {
-        F& parent;
-        CR(*continuation)(F&) ;
-        launch policy_;
-        promise<R> next;
-
-        future_continuation(F& f, CR(*c)(F&)) :
-          parent(f),
-          continuation(c),
-          policy_(f.launch_policy()),
-          next()
-        {}
-        future_continuation(F& f, CR(*c)(F&), launch policy) :
-          parent(f),
-          continuation(c),
-          policy_(policy),
-          next()
-        {}
-        ~future_continuation()
-        {}
-
-        void do_continuation(boost::unique_lock<boost::mutex>& lk)
-        {
-          try
-          {
-            lk.unlock();
-            // fixme what to do depending on inherits_launch_policy_ and policy_?
+//          }
+//          catch (...)
+//          {
+//            next.set_exception(boost::current_exception());
+//          }
+//        }
+//      private:
+//
+//        future_continuation(future_continuation const&);
+//        future_continuation& operator=(future_continuation const&);
+//      };
+//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+//      template <typename F, typename R, typename CR>
+//      struct future_continuation<F,R,CR(*)(F&)> : future_object<R>
+//      {
+//        F& parent;
+//        CR(*continuation)(F&) ;
+//        launch policy_;
+//
+//        future_continuation(F& f, CR(*c)(F&)) :
+//          parent(f),
+//          continuation(c),
+//          policy_(f.launch_policy()),
+//          next()
+//        {}
+//        future_continuation(F& f, CR(*c)(F&), launch policy) :
+//          parent(f),
+//          continuation(c),
+//          policy_(policy),
+//          next()
+//        {}
+//        ~future_continuation()
+//        {}
+//
+//        void start_continuation(boost::unique_lock<boost::mutex>& lk)
+//        {
+//          try
+//          {
+//            lk.unlock();
+//            // fixme what to do depending on inherits_launch_policy_ and policy_?
 //            if (int(policy_) & int(launch::deferred))
-            {
-              R val = continuation(parent);
-              next.set_value(boost::move(val));
-            }
+//            {
+//              R val = continuation(parent);
+//              next.set_value(boost::move(val));
+//            }
 //            else
 //            {
 //              BOOST_THREAD_FUTURE<R> f = async(policy_, continuation, boost::ref(parent));
 //              R val = f.get();
 //              next.set_value(boost::move(val));
 //            }
-          }
-          catch (...)
-          {
-            next.set_exception(boost::current_exception());
-          }
-        }
-      private:
-
-        future_continuation(future_continuation const&);
-        future_continuation& operator=(future_continuation const&);
-      };
-#endif
+//          }
+//          catch (...)
+//          {
+//            next.set_exception(boost::current_exception());
+//          }
+//        }
+//      private:
+//
+//        future_continuation(future_continuation const&);
+//        future_continuation& operator=(future_continuation const&);
+//      };
+//#endif
   }
 
   ////////////////////////////////
@@ -3470,119 +3814,125 @@
   template <typename R>
   template <typename F>
   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type>
-  BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_RV_REF(F) func)
+  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;
 
-    if (this->future_)
-    {
-      boost::unique_lock<boost::mutex> lock(this->future_->mutex);
-      detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, F > *ptr =
-          new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, F>(*this, boost::forward<F>(func), policy);
-      if (ptr==0)
+      if (this->future_==0)
       {
-        return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
+        // fixme what to do when the future has no associated state?
+        return BOOST_THREAD_FUTURE<future_type>();
       }
-      this->future_->set_continuation_ptr(ptr, lock);
-      return BOOST_THREAD_MAKE_RV_REF(ptr->next.get_future());
-    }
-    else
+
+      boost::unique_lock<boost::mutex> lock(this->future_->mutex);
+      if (int(policy) & int(launch::async))
     {
-      // fixme what to do when the future has no associated state?
-      return BOOST_THREAD_FUTURE<future_type>();
+      return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation<BOOST_THREAD_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<BOOST_THREAD_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(BOOST_THREAD_FUTURE<R>&)>::type>
-  BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_RV_REF(F) func)
+  BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func)
   {
 
     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type future_type;
 
-    if (this->future_)
+    if (this->future_==0)
     {
-      boost::unique_lock<boost::mutex> lock(this->future_->mutex);
-      detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, F > *ptr =
-          new
-          //BOOST_THREAD_MAKE_RV_REF((
-              detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, F>(*this, boost::forward<F>(func))
-              //))
-              ;
-      if (ptr==0)
-      {
-        return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
-      }
-      this->future_->set_continuation_ptr(ptr, lock);
-      return ptr->next.get_future();
-    } else {
+      //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_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
+      return BOOST_THREAD_FUTURE<future_type>();
     }
 
-  }
-#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
-  template <typename R>
-  template<typename RF>
-  BOOST_THREAD_FUTURE<RF>
-  BOOST_THREAD_FUTURE<R>::then(RF(*func)(BOOST_THREAD_FUTURE<R>&))
-  {
-
-    typedef RF future_type;
-
-    if (this->future_)
+    boost::unique_lock<boost::mutex> lock(this->future_->mutex);
+    if (int(this->launch_policy()) & int(launch::async))
     {
-      boost::unique_lock<boost::mutex> lock(this->future_->mutex);
-      detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
-          new
-          //BOOST_THREAD_MAKE_RV_REF((
-              detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func)
-           //   ))
-      ;
-      if (ptr==0)
-      {
-        return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
-      }
-      this->future_->set_continuation_ptr(ptr, lock);
-      return ptr->next.get_future();
-    } else {
-      // fixme what to do when the future has no associated state?
-      return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
+      return boost::detail::make_future_async_continuation<BOOST_THREAD_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<BOOST_THREAD_FUTURE<R>, future_type, F>(
+          lock, *this, boost::forward<F>(func)
+      );
     }
-
-  }
-  template <typename R>
-  template<typename RF>
-  BOOST_THREAD_FUTURE<RF>
-  BOOST_THREAD_FUTURE<R>::then(launch policy, RF(*func)(BOOST_THREAD_FUTURE<R>&))
-  {
-
-    typedef RF future_type;
-
-    if (this->future_)
+    else
     {
-      boost::unique_lock<boost::mutex> lock(this->future_->mutex);
-      detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
-          new
-          //BOOST_THREAD_MAKE_RV_REF((
-              detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func, policy)
-            //  ))
-      ;
-      if (ptr==0)
-      {
-        return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
-      }
-      this->future_->set_continuation_ptr(ptr, lock);
-      return ptr->next.get_future();
-    } else {
-      // fixme what to do when the future has no associated state?
-      return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
+      // fixme what to do when the policy is invalid?
+      return BOOST_THREAD_FUTURE<future_type>();
     }
-
   }
-#endif
+//#if 0 && defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+//  template <typename R>
+//  template<typename RF>
+//  BOOST_THREAD_FUTURE<RF>
+//  BOOST_THREAD_FUTURE<R>::then(RF(*func)(BOOST_THREAD_FUTURE<R>&))
+//  {
+//
+//    typedef RF future_type;
+//
+//    if (this->future_)
+//    {
+//      boost::unique_lock<boost::mutex> lock(this->future_->mutex);
+//      detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
+//          new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func);
+//      if (ptr==0)
+//      {
+//        return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
+//      }
+//      this->future_->set_continuation_ptr(ptr, lock);
+//      return ptr->get_future();
+//    } else {
+//      // fixme what to do when the future has no associated state?
+//      return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
+//    }
+//
+//  }
+//  template <typename R>
+//  template<typename RF>
+//  BOOST_THREAD_FUTURE<RF>
+//  BOOST_THREAD_FUTURE<R>::then(launch policy, RF(*func)(BOOST_THREAD_FUTURE<R>&))
+//  {
+//
+//    typedef RF future_type;
+//
+//    if (this->future_)
+//    {
+//      boost::unique_lock<boost::mutex> lock(this->future_->mutex);
+//      detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
+//          new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func, policy);
+//      if (ptr==0)
+//      {
+//        return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
+//      }
+//      this->future_->set_continuation_ptr(ptr, lock);
+//      return ptr->get_future();
+//    } else {
+//      // fixme what to do when the future has no associated state?
+//      return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
+//    }
+//
+//  }
+//#endif
 
 #endif
 
Modified: branches/release/libs/thread/example/future_then.cpp
==============================================================================
--- branches/release/libs/thread/example/future_then.cpp	(original)
+++ branches/release/libs/thread/example/future_then.cpp	2013-04-08 13:23:02 EDT (Mon, 08 Apr 2013)
@@ -1,12 +1,11 @@
-// Copyright (C) 2012 Vicente Botet
+// Copyright (C) 2012-2013 Vicente Botet
 //
 //  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)
 
-//#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_VERSION 4
 #define BOOST_THREAD_USES_LOG
 #define BOOST_THREAD_USES_LOG_THREAD_ID
-#define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
 
 #include <boost/thread/detail/log.hpp>
 #include <boost/thread/future.hpp>
@@ -46,11 +45,8 @@
   try
   {
     boost::future<int> f1 = boost::async(boost::launch::async, &p1);
-    BOOST_THREAD_LOG <<  BOOST_THREAD_END_LOG;
     boost::future<int> f2 = f1.then(&p2);
-    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-    int i = f2.get();
-    BOOST_THREAD_LOG << i << BOOST_THREAD_END_LOG;
+    (void)f2.get();
   }
   catch (std::exception& ex)
   {
Modified: branches/release/libs/thread/example/tennis.cpp
==============================================================================
--- branches/release/libs/thread/example/tennis.cpp	(original)
+++ branches/release/libs/thread/example/tennis.cpp	2013-04-08 13:23:02 EDT (Mon, 08 Apr 2013)
@@ -39,11 +39,10 @@
     return 0;
 }
 
-void player(void* param)
+void player(int active)
 {
     boost::unique_lock<boost::mutex> lock(mutex);
 
-    int active = (int)param;
     int other = active == PLAYER_A ? PLAYER_B : PLAYER_A;
 
     while (state < GAME_OVER)
@@ -100,8 +99,8 @@
 {
     state = START;
 
-    boost::thread thrda(thread_adapter(&player, (void*)PLAYER_A));
-    boost::thread thrdb(thread_adapter(&player, (void*)PLAYER_B));
+    boost::thread thrda(&player, PLAYER_A);
+    boost::thread thrdb(&player, PLAYER_B);
 
     boost::xtime xt;
     boost::xtime_get(&xt, boost::TIME_UTC_);
@@ -112,7 +111,7 @@
         std::cout << "---Noise ON..." << std::endl;
     }
 
-    for (int i = 0; i < 1000000000; ++i)
+    for (int i = 0; i < 10; ++i)
         cond.notify_all();
 
     {
Modified: branches/release/libs/thread/test/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/test/Jamfile.v2	(original)
+++ branches/release/libs/thread/test/Jamfile.v2	2013-04-08 13:23:02 EDT (Mon, 08 Apr 2013)
@@ -184,6 +184,15 @@
     ;
 }
 
+rule thread-compile ( sources : reqs * : name )
+{
+    return
+    [ compile $(sources)
+        : $(reqs)
+        : $(name) ]
+    ;
+}
+
 {
     test-suite t_threads
     :
@@ -334,7 +343,10 @@
           [ thread-run2-noit ./sync/futures/future/move_ctor_pass.cpp : future__move_ctor_p ]
           [ thread-run2-noit ./sync/futures/future/move_assign_pass.cpp : future__move_asign_p ]
           [ thread-run2-noit ./sync/futures/future/share_pass.cpp : future__share_p ]
-          #[ thread-run2-noit ./sync/futures/future/then_pass.cpp : future__then_p ]
+          [ thread-run2-noit ./sync/futures/future/wait_pass.cpp : future__wait_p ]
+          [ thread-run2-noit ./sync/futures/future/wait_for_pass.cpp : future__wait_for_p ]
+          [ thread-run2-noit ./sync/futures/future/wait_until_pass.cpp : future__wait_until_p ]
+          [ thread-run2-noit ./sync/futures/future/then_pass.cpp : future__then_p ]
     ;
 
     #explicit ts_shared_future ;
@@ -347,6 +359,9 @@
           [ thread-run2-noit ./sync/futures/shared_future/get_pass.cpp : shared_future__get_p ]
           [ thread-run2-noit ./sync/futures/shared_future/move_ctor_pass.cpp : shared_future__move_ctor_p ]
           [ thread-run2-noit ./sync/futures/shared_future/move_assign_pass.cpp : shared_future__move_asign_p ]
+          [ thread-run2-noit ./sync/futures/shared_future/wait_pass.cpp : shared_future__wait_p ]
+          [ thread-run2-noit ./sync/futures/shared_future/wait_for_pass.cpp : shared_future__wait_for_p ]
+          [ thread-run2-noit ./sync/futures/shared_future/wait_until_pass.cpp : shared_future__wait_until_p ]
     ;
 
     #explicit ts_packaged_task ;
@@ -615,6 +630,7 @@
           [ thread-run2-noit ./threads/thread/assign/move_pass.cpp : thread__assign__move_p ]
           [ thread-compile-fail ./threads/thread/constr/copy_fail.cpp : : thread__constr__copy_f ]
           [ thread-run2-noit ./threads/thread/constr/default_pass.cpp : thread__constr__default_p ]
+          [ thread-run-lib2 ./threads/thread/constr/lambda_pass.cpp : thread__constr__lambda_p ]
           [ thread-run-lib2 ./threads/thread/constr/F_pass.cpp : thread__constr__F_p ]
           [ thread-run-lib2 ./threads/thread/constr/FArgs_pass.cpp : thread__constr__FArgs_p ]
           [ thread-run2-noit ./threads/thread/constr/Frvalue_pass.cpp : thread__constr__Frvalue_p ]
@@ -645,31 +661,32 @@
     test-suite ts_examples
     :
           [ thread-run2-noit ../example/monitor.cpp : ex_monitor ]
-          [ compile ../example/starvephil.cpp ]
-          #[ compile ../example/tennis.cpp ]
-          [ compile ../example/condition.cpp ]
+          [ thread-compile ../example/starvephil.cpp : : ex_starvephil ]
+          [ thread-run2 ../example/tennis.cpp : ex_tennis ]
+          [ thread-compile ../example/condition.cpp : : ex_condition ]
           [ thread-run2-noit ../example/mutex.cpp : ex_mutex ]
           [ thread-run2-noit ../example/once.cpp : ex_once ]
           [ thread-run2-noit ../example/recursive_mutex.cpp : ex_recursive_mutex ]
           [ thread-run2-noit ../example/thread.cpp : ex_thread ]
           [ thread-run2-noit ../example/thread_group.cpp : ex_thread_group ]
           [ thread-run2-noit ../example/tss.cpp : ex_tss ]
-          [ thread-run ../example/xtime.cpp ]
-          [ thread-run ../example/shared_monitor.cpp ]
-          [ thread-run ../example/shared_mutex.cpp ]
+          [ thread-run2 ../example/xtime.cpp : ex_xtime ]
+          [ thread-run2 ../example/shared_monitor.cpp : ex_shared_monitor ]
+          [ thread-run2 ../example/shared_mutex.cpp : ex_shared_mutex ]
           #[ thread-run ../example/vhh_shared_monitor.cpp ]
           #[ thread-run ../example/vhh_shared_mutex.cpp ]
-          [ thread-run ../example/make_future.cpp ]
-          #[ thread-run ../example/future_then.cpp ]
+          [ thread-run2 ../example/make_future.cpp : ex_make_future ]
+          [ thread-run2 ../example/future_then.cpp : ex_future_then ]
           #[ thread-run2-noit ../example/synchronized_value.cpp : ex_synchronized_value ]
           #[ thread-run2-noit ../example/synchronized_person.cpp : ex_synchronized_person ]
           [ thread-run2-noit ../example/thread_guard.cpp : ex_thread_guard ]
           [ thread-run2-noit ../example/scoped_thread.cpp : ex_scoped_thread ]
           [ thread-run2-noit ../example/strict_lock.cpp : ex_strict_lock ]
           [ thread-run2-noit ../example/ba_externallly_locked.cpp : ex_ba_externallly_locked ]
-          [ thread-run ../example/producer_consumer_bounded.cpp ]
-          [ thread-run ../example/producer_consumer.cpp ]
-          [ thread-run ../example/not_interleaved.cpp ]
+          [ thread-run2 ../example/producer_consumer_bounded.cpp : ex_producer_consumer_bounded ]
+          [ thread-run2 ../example/producer_consumer.cpp : ex_producer_consumer ]
+          [ thread-run2 ../example/not_interleaved.cpp : ex_not_interleaved ]
+          [ thread-run2 ../example/lambda_future.cpp : ex_lambda_future ]
 
     ;
 
@@ -739,6 +756,7 @@
           #[ 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: branches/release/libs/thread/test/sync/futures/async/async_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/async/async_pass.cpp	(original)
+++ branches/release/libs/thread/test/sync/futures/async/async_pass.cpp	2013-04-08 13:23:02 EDT (Mon, 08 Apr 2013)
@@ -197,12 +197,12 @@
   {
     try {
     boost::future<int> f = boost::async(boost::launch::async, BOOST_THREAD_MAKE_RV_REF(MoveOnly()));
-    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;
+//    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");
Modified: branches/release/libs/thread/test/sync/futures/future/get_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/future/get_pass.cpp	(original)
+++ branches/release/libs/thread/test/sync/futures/future/get_pass.cpp	2013-04-08 13:23:02 EDT (Mon, 08 Apr 2013)
@@ -93,20 +93,20 @@
   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
   {
       typedef int T;
-//      {
-//          boost::promise<T> p;
-//          boost::future<T> f = p.get_future();
-//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
-//           boost::thread(func1, boost::move(p)).detach();
-//#else
-//           p.set_value(3);
-//#endif
-//          BOOST_TEST(f.valid());
-//          BOOST_TEST(f.get() == 3);
-//#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
-//          BOOST_TEST(!f.valid());
-//#endif
-//      }
+      {
+          boost::promise<T> p;
+          boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+           boost::thread(func1, boost::move(p)).detach();
+#else
+           p.set_value(3);
+#endif
+          BOOST_TEST(f.valid());
+          BOOST_TEST(f.get() == 3);
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+          BOOST_TEST(!f.valid());
+#endif
+      }
       BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
       {
           boost::promise<T> p;
Modified: branches/release/libs/thread/test/sync/futures/future/then_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/future/then_pass.cpp	(original)
+++ branches/release/libs/thread/test/sync/futures/future/then_pass.cpp	2013-04-08 13:23:02 EDT (Mon, 08 Apr 2013)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Vicente J. Botet Escriba
+// Copyright (C) 2012-2013 Vicente Botet
 //
 //  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)
@@ -11,7 +11,6 @@
 // auto then(F&& func) -> future<decltype(func(*this))>;
 
 #define BOOST_THREAD_VERSION 4
-#define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
 #define BOOST_THREAD_USES_LOG
 #define BOOST_THREAD_USES_LOG_THREAD_ID
 #include <boost/thread/detail/log.hpp>
@@ -23,61 +22,68 @@
 
 int p1()
 {
+  BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
+  boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+  BOOST_THREAD_LOG << "p1 >"  << BOOST_THREAD_END_LOG;
   return 1;
 }
 
 int p2(boost::future<int>& f)
 {
-  return 2 * f.get();
+  BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+  BOOST_TEST(f.valid());
+  int i = f.get();
+  boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+  BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+  return 2 * i;
 }
 
 int main()
 {
+  {
+    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+    boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+    BOOST_TEST(f1.valid());
+    boost::future<int> f2 = f1.then(&p2);
+    BOOST_TEST(f2.valid());
+    try
+    {
+      BOOST_TEST(f2.get()==2);
+    }
+    catch (std::exception& ex)
+    {
+      BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+      BOOST_TEST(false);
+    }
+    catch (...)
+    {
+      BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+      BOOST_TEST(false);
+    }
+  }
   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-  boost::future<int> f1 = boost::async(boost::launch::async, p1);
-  BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-  boost::future<int> f2 = f1.then(p2);
-  BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-  try
   {
+    boost::future<int> f2 = boost::async(p1).then(&p2);
     BOOST_TEST(f2.get()==2);
-    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
   }
-  catch (std::exception& ex)
+  BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
   {
-    BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
-    BOOST_ASSERT(false);
+    boost::future<int> f1 = boost::async(p1);
+    boost::future<int> f21 = f1.then(&p2);
+    boost::future<int> f2= f21.then(&p2);
+    BOOST_TEST(f2.get()==4);
   }
-  catch (...)
+  BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
   {
-    BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
-    BOOST_ASSERT(false);
+    boost::future<int> f1 = boost::async(p1);
+    boost::future<int> f2= f1.then(&p2).then(&p2);
+    BOOST_TEST(f2.get()==4);
   }
   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-
-//  {
-//    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-//    boost::future<int> f2 = boost::async(p1).then(p2);
-//    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-//    BOOST_TEST(f2.get()==2);
-//    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-//  }
-//  {
-//    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-//    boost::future<int> f1 = boost::async(p1);
-//    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-//    boost::future<int> f2 = f1.then(p2).then(p2);
-//    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-//    BOOST_TEST(f2.get()==4);
-//    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-//  }
-//  {
-//    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-//    boost::future<int> f2 = boost::async(p1).then(p2).then(p2);
-//    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-//    BOOST_TEST(f2.get()==4);
-//    BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
-//  }
+  {
+    boost::future<int> f2 = boost::async(p1).then(&p2).then(&p2);
+    BOOST_TEST(f2.get()==4);
+  }
 
   return boost::report_errors();
 }