$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r83949 - in trunk: boost/thread libs/thread/doc libs/thread/example
From: vicente.botet_at_[hidden]
Date: 2013-04-18 02:43:20
Author: viboes
Date: 2013-04-18 02:43:19 EDT (Thu, 18 Apr 2013)
New Revision: 83949
URL: http://svn.boost.org/trac/boost/changeset/83949
Log:
Thread: add missing joinable in scoped_thread #8451 + construction from F, Args.
Text files modified: 
   trunk/boost/thread/scoped_thread.hpp        |    56 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/thread/doc/scoped_thread.qbk     |    43 +++++++++++++++++++++++++++++-          
   trunk/libs/thread/example/scoped_thread.cpp |    18 ++++++++++++                            
   3 files changed, 115 insertions(+), 2 deletions(-)
Modified: trunk/boost/thread/scoped_thread.hpp
==============================================================================
--- trunk/boost/thread/scoped_thread.hpp	(original)
+++ trunk/boost/thread/scoped_thread.hpp	2013-04-18 02:43:19 EDT (Thu, 18 Apr 2013)
@@ -38,10 +38,35 @@
   class strict_scoped_thread
   {
     thread t_;
+    struct dummy;
   public:
 
     BOOST_THREAD_NO_COPYABLE( strict_scoped_thread) /// non copyable
 
+    /*
+     *
+     */
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+    template <class F, class ...Args>
+    explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args,
+        typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0) :
+      t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
+#else
+    template <class F>
+    explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f,
+        typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0) :
+      t_(boost::forward<F>(f)) {}
+    template <class F, class A1>
+    strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) :
+      t_(boost::forward<F>(f), boost::forward<A1>(a1)) {}
+    template <class F, class A1, class A2>
+    strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) :
+      t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2)) {}
+    template <class F, class A1, class A2, class A3>
+    strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2, BOOST_THREAD_FWD_REF(A3) a3) :
+      t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)) {}
+#endif
+
     /**
      * Constructor from the thread to own.
      *
@@ -91,6 +116,7 @@
   class scoped_thread
   {
     thread t_;
+    struct dummy;
   public:
 
     typedef thread::id id;
@@ -108,6 +134,31 @@
     }
 
     /**
+     *
+     */
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+    template <class F, class ...Args>
+    explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args,
+        typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0) :
+      t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
+#else
+    template <class F>
+    explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f,
+        typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0) :
+      t_(boost::forward<F>(f)) {}
+    template <class F, class A1>
+    scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) :
+      t_(boost::forward<F>(f), boost::forward<A1>(a1)) {}
+    template <class F, class A1, class A2>
+    scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) :
+      t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2)) {}
+    template <class F, class A1, class A2, class A3>
+    scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2, BOOST_THREAD_FWD_REF(A3) a3) :
+      t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)) {}
+
+#endif
+    /**
      * Constructor from the thread to own.
      *
      * @param t: the thread to own.
@@ -195,6 +246,11 @@
       return t_.native_handle();
     }
 
+    bool joinable() const BOOST_NOEXCEPT
+    {
+      return t_.joinable();
+    }
+
 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     void interrupt()
     {
Modified: trunk/libs/thread/doc/scoped_thread.qbk
==============================================================================
--- trunk/libs/thread/doc/scoped_thread.qbk	(original)
+++ trunk/libs/thread/doc/scoped_thread.qbk	2013-04-18 02:43:19 EDT (Thu, 18 Apr 2013)
@@ -105,6 +105,8 @@
     strict_scoped_thread& operator=(strict_scoped_thread const&) = delete;
 
     explicit strict_scoped_thread(thread&& t) noexcept;
+    template <typename F&&, typename ...Args>
+    explicit strict_scoped_thread(F&&, Args&&...);
 
     ~strict_scoped_thread();
 
@@ -125,7 +127,7 @@
 
   boost::strict_scoped_thread<> t((boost::thread(F)));
 
-[section:default_constructor Default Constructor]
+[section:default_constructor Constructor from a __thread]
 
     explicit strict_scoped_thread(thread&& t) noexcept;
 
@@ -139,6 +141,24 @@
 
 [endsect]
 
+
+[section:call_constructor Move Constructor from a Callable]
+
+        template <typename F&&, typename ...Args>
+        explicit strict_scoped_thread(F&&, Args&&...);
+
+[variablelist
+
+[[Effects:] [Construct a internal thread in place.]]
+
+[[Postconditions:] [`*this.t_` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
+
+[[Throws:] [Any exception the thread construction can throw.]]
+
+]
+
+[endsect]
+
 [section:destructor Destructor]
 
     ~strict_scoped_thread();
@@ -149,7 +169,6 @@
 
 [[Throws:] [Nothing: The `CallableThread()(t_)` should not throw when joining the thread as the scoped variable is on a scope outside the thread function.]]
 
-
 ]
 
 [endsect]
@@ -160,6 +179,7 @@
 
     #include <boost/thread/scoped_thread.hpp>
 
+    template <class CallableThread>
     class scoped_thread
     {
       thread t_; // for exposition purposes only
@@ -169,6 +189,8 @@
         scoped_thread& operator=(const scoped_thread&) = delete;
 
         explicit scoped_thread(thread&& th) noexcept;
+        template <typename F&&, typename ...Args>
+        explicit strict_scoped_thread(F&&, Args&&...);
 
         ~scoped_thread();
 
@@ -298,6 +320,23 @@
 
 [endsect]
 
+[section:call_constructor Move Constructor from a Callable]
+
+        template <typename F&&, typename ...Args>
+        explicit strict_scoped_thread(F&&, Args&&...);
+
+[variablelist
+
+[[Effects:] [Construct a internal thread in place.]]
+
+[[Postconditions:] [`*this.t_` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
+
+[[Throws:] [Any exception the thread construction can throw.]]
+
+]
+
+[endsect]
+
 
 [section:destructor Destructor]
 
Modified: trunk/libs/thread/example/scoped_thread.cpp
==============================================================================
--- trunk/libs/thread/example/scoped_thread.cpp	(original)
+++ trunk/libs/thread/example/scoped_thread.cpp	2013-04-18 02:43:19 EDT (Thu, 18 Apr 2013)
@@ -64,6 +64,24 @@
 //    do_something_in_current_thread();
 //    do_something_with_current_thread(boost::thread(g));
 //  }
+  {
+    int some_local_state;
+    boost::scoped_thread<> t( (boost::thread(func(some_local_state))));
+
+    if (t.joinable())
+      t.join();
+    else
+      do_something_in_current_thread();
+  }
+  {
+    int some_local_state;
+    boost::thread t(( func(some_local_state) ));
+    boost::scoped_thread<> g( (boost::move(t)) );
+    t.detach();
+
+    do_something_in_current_thread();
+  }
+
   return 0;
 }